summaryrefslogtreecommitdiff
path: root/src/nu_server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nu_server.c')
-rwxr-xr-xsrc/nu_server.c116
1 files changed, 116 insertions, 0 deletions
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}