summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorerdgeist <>2003-12-01 14:35:28 +0000
committererdgeist <>2003-12-01 14:35:28 +0000
commitc0e83b6e7a814a85b76ea22d6306b7027a3222f9 (patch)
tree3e8be11673cefa5e5e7a5c3db38f1b7ec4f8d87e
kick off
-rwxr-xr-xbin/.cvsignore0
-rwxr-xr-xsrc/nu_header.h144
-rwxr-xr-xsrc/nu_server.c116
3 files changed, 260 insertions, 0 deletions
diff --git a/bin/.cvsignore b/bin/.cvsignore
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/bin/.cvsignore
diff --git a/src/nu_header.h b/src/nu_header.h
new file mode 100755
index 0000000..0afdbaf
--- /dev/null
+++ b/src/nu_header.h
@@ -0,0 +1,144 @@
1typedef unsigned char BYTE;
2typedef unsigned short WORD;
3typedef unsigned long DWORD;
4
5typedef struct {
6 BYTE netbios_command;
7 BYTE netbios_flags;
8 WORD netbios_size;
9/*BYTE Protocol[4]; Protocol identifier 0xFF,"SMB" */
10 DWORD Protocol; /* For faster compare */
11 BYTE Command; /* Command Code, look below */
12 union {
13 struct {
14 BYTE ErrorClass;
15 BYTE Reserved;
16 WORD Error;
17 } DosError;
18 DWORD Status;
19 } Status;
20 BYTE Flags;
21 WORD Flags2;
22 union {
23 WORD Pad[6]; /* Ensure 12 bytes len */
24 struct {
25 WORD PidHigh;
26 BYTE SecuritySignature[8];
27 } Extra;
28 };
29 WORD TreeID;
30 WORD ProcessID;
31 WORD UserID;
32 WORD MultiplexID;
33 BYTE WordCount;
34 WORD ParameterWords[0];
35} SMB_HEADER;
36
37typedef struct {
38 WORD ByteCount;
39 BYTE Buffer[0];
40} SMB_HEADER2;
41
42/* This is the protocol identifier, each smb
43 request must begin with this double word
44*/
45#define SMB_HEADER_PROTOCOL_MAGIC 0xff534d42
46
47/* These are all valid SMB requests known from the document
48 http://www.snia.org/tech_activities/CIFS/CIFS_TR-1p00_FINAL.pdf
49
50 However, we only intend to implement the core smb command set,
51 also known as dialect "PC NETWORK PROGRAM 1.0" and still only
52 a read-only subset of this.
53*/
54
55enum {
56 SMB_COM_CREATE_DIRECTORY = 0x00,
57 SMB_COM_DELETE_DIRECTORY = 0x01,
58 SMB_COM_OPEN = 0x02,
59 SMB_COM_CREATE = 0x03,
60 SMB_COM_CLOSE = 0x04,
61 SMB_COM_FLUSH = 0x05,
62 SMB_COM_DELETE = 0x06,
63 SMB_COM_RENAME = 0x07,
64 SMB_COM_QUERY_INFORMATION = 0x08,
65 SMB_COM_SET_INFORMATION = 0x09,
66 SMB_COM_READ = 0x0A,
67 SMB_COM_WRITE = 0x0B,
68 SMB_COM_LOCK_BYTE_RANGE = 0x0C,
69 SMB_COM_UNLOCK_BYTE_RANGE = 0x0D,
70 SMB_COM_CREATE_TEMPORARY = 0x0E,
71 SMB_COM_CREATE_NEW = 0x0F,
72
73 SMB_COM_CHECK_DIRECTORY = 0x10,
74 SMB_COM_PROCESS_EXIT = 0x11,
75 SMB_COM_SEEK = 0x12,
76 SMB_COM_LOCK_AND_READ = 0x13,
77 SMB_COM_WRITE_AND_UNLOCK = 0x14,
78 /* ... */
79 SMB_COM_READ_RAW = 0x1A,
80 SMB_COM_READ_MPX = 0x1B,
81 SMB_COM_READ_MPX_SECONDARY = 0x1C,
82 SMB_COM_WRITE_RAW = 0x1D,
83 SMB_COM_WRITE_MPX = 0x1E,
84 SMB_COM_WRITE_MPX_SECONDARY = 0x1F,
85
86 SMB_COM_WRITE_COMPLETE = 0x20,
87 SMB_COM_QUERY_SERVER = 0x21,
88 SMB_COM_SET_INFORMATION2 = 0x22,
89 SMB_COM_QUERY_INFORMATION2 = 0x23,
90 SMB_COM_LOCKING_ANDX = 0x24,
91 SMB_COM_TRANSACTION = 0x25,
92 SMB_COM_TRANSACTION_SECONDARY = 0x26,
93 SMB_COM_IOCTL = 0x27,
94 SMB_COM_IOCTL_SECONDARY = 0x28,
95 SMB_COM_COPY = 0x29,
96 SMB_COM_MOVE = 0x2A,
97 SMB_COM_ECHO = 0x2B,
98 SMB_COM_WRITE_AND_CLOSE = 0x2C,
99 SMB_COM_OPEN_ANDX = 0x2D,
100 SMB_COM_READ_ANDX = 0x2E,
101 SMB_COM_WRITE_ANDX = 0x2F,
102
103 SMB_COM_NEW_FILE_SIZE = 0x30,
104 SMB_COM_CLOSE_AND_TREE_DISC = 0x31,
105 SMB_COM_TRANSACTION2 = 0x32,
106 SMB_COM_TRANSACTION2_SECONDARY = 0x33,
107 SMB_COM_FIND_CLOSE2 = 0x34,
108 SMB_COM_FIND_NOTIFY_CLOSE = 0x35,
109 /* ... */
110
111 SMB_COM_TREE_CONNECT = 0x70,
112 SMB_COM_TREE_DISCONNECT = 0x71,
113 SMB_COM_NEGOTIATE = 0x72,
114 SMB_COM_SESSION_SETUP_ANDX = 0x73,
115 SMB_COM_LOGOFF_ANDX = 0x74,
116 SMB_COM_TREE_CONNECT_ANDX = 0x75,
117 /* ... */
118
119 SMB_COM_QUERY_INFORMATION_DISK = 0x80,
120 SMB_COM_SEARCH = 0x81,
121 SMB_COM_FIND = 0x82,
122 SMB_COM_FIND_UNIQUE = 0x83,
123 SMB_COM_FIND_CLOSE = 0x84,
124 /* ... */
125
126 SMB_COM_NT_TRANSACT = 0xA0,
127 SMB_COM_NT_TRANSACT_SECONDARY = 0xA1,
128 SMB_COM_NT_CREATE_ANDX = 0xA2,
129 /* ... */
130 SMB_COM_NT_CANCEL = 0xA4,
131 SMB_COM_NT_RENAME = 0xA5,
132 /* ... */
133
134 SMB_COM_OPEN_PRINT_FILE = 0xC0,
135 SMB_COM_WRITE_PRINT_FILE = 0xC1,
136 SMB_COM_CLOSE_PRINT_FILE = 0xC2,
137 SMB_COM_GET_PRINT_QUEUE = 0xC3,
138 /* ... */
139
140 SMB_COM_READ_BULK = 0xD8,
141 SMB_COM_WRITE_BULK = 0xD9,
142 SMB_COM_WRITE_BULK_DATA = 0xDA
143} SMB_COMMAND;
144
diff --git a/src/nu_server.c b/src/nu_server.c
new file mode 100755
index 0000000..942be1b
--- /dev/null
+++ b/src/nu_server.c
@@ -0,0 +1,116 @@
1#include <signal.h>
2#include <sys/types.h>
3#include <sys/socket.h>
4#include <netinet/in.h>
5#include <stdio.h>
6#include <sys/ioctl.h>
7
8#include "nu_header.h"
9
10static void bailout( char *reason );
11static mainsock = -1;
12static childsock = -1;
13
14static void netbios_read( SMB_HEADER **buf) {
15 BYTE bytes[4];
16 ssize_t bytesread, bytestoread;
17
18 if( read( childsock, bytes, 4) < 4 )
19 bailout( "Short read." );
20 bytestoread = htons(*(WORD*)(2+bytes));
21 if( (*buf = (SMB_HEADER*)realloc( *buf, 4 + bytestoread )) == NULL)
22 bailout( "Out of memory");
23 *(DWORD*)*buf = *(DWORD*)bytes;
24 bytesread = read( childsock, ((BYTE*)buf) + 4, bytestoread);
25 if( bytesread != bytestoread )
26 bailout( "Short read." );
27}
28
29static void netbios_write( BYTE command, BYTE *buf, WORD size ) {
30 BYTE netbios_header[4] = { command, 0, size >> 8, size & 255 };
31 if( write( childsock, netbios_header, 4 ) <= 0 ||
32 write( childsock, buf, size ) < 0 )
33 bailout( "Write failed." );
34}
35
36static void child( ) {
37 SMB_HEADER *inpacket = NULL;
38 DWORD bytesread;
39
40 /* I should spare that code... */
41 if( mainsock != -1 ) { close( mainsock ); mainsock = -1; }
42
43 /* Try to answer first netbios packet */
44 netbios_read( &inpacket );
45 if( inpacket->netbios_command != 0x81 )
46 bailout( "No session request");
47 netbios_write( 0x82, NULL, 0 );
48
49 while( 1 ) {
50 netbios_read( &inpacket );
51 if( inpacket->netbios_command != 0 )
52 bailout( "Unhandled netbios command" );
53 if( inpacket->Protocol != SMB_HEADER_PROTOCOL_MAGIC )
54 bailout( "Protocol identifier mismatch");
55
56 switch( inpacket->Command ) {
57 case SMB_COM_NEGOTIATE:
58 {
59 BYTE outblock[5] = { 0xff,0,0,0,0 };
60 netbios_write( 0, outblock, sizeof( outblock ));
61 break;
62 }
63 default:
64 {
65 fprintf( stderr, "Got message: %02X\n", inpacket->Command );
66 break;
67 }
68 }
69
70 } /* End main loop */
71}
72
73void sigint( int reason ) { bailout( "User interrupt." ); }
74
75int main()
76{
77 struct sockaddr_in sa;
78 int l=1;
79
80 signal( SIGINT, sigint);
81
82 bzero( &sa, sizeof( sa));
83 sa.sin_family = PF_INET;
84 sa.sin_port = htons( 139 );
85 sa.sin_addr.s_addr = INADDR_ANY;
86
87 if( ( mainsock = socket( PF_INET, SOCK_STREAM, 0) ) == -1)
88 bailout( "Could not open socket");
89 setsockopt( mainsock, SOL_SOCKET, SO_REUSEPORT, &l, sizeof(l));
90 if( bind( mainsock, (struct sockaddr *)&sa, sizeof( sa)) != 0)
91 bailout( "Could not bind socket");
92 if( listen( mainsock, 1024) != 0 )
93 bailout( "Could not make socket listen");
94
95 while( 1 ) {
96 struct sockaddr otherend;
97 int size = sizeof( otherend );
98
99 if( ( childsock = accept( mainsock, &otherend, &size) ) == -1)
100 bailout( "Socket Broke.");
101 if (!fork()) child( );
102 }
103}
104
105/* Graceful exit. */
106static void bailout( char *reason) {
107 fputs( reason, stderr);
108 fputs( "\nCleaning up.\n", stderr);
109 if( mainsock != -1 )
110 close( mainsock );
111 if( childsock != -1 ) {
112 shutdown( childsock, SHUT_RDWR);
113 close( childsock );
114 }
115 exit( 0 );
116}