]> git.sesse.net Git - nbtscanner/blob - socket.c
Import nbtscanner 0.2.0.
[nbtscanner] / socket.c
1 /*
2  * nbtscanner -- a tool for scanning large networks for SMB servers.
3  *
4  * socket.c: Most functions that are related to TCP/IP (socket) use.
5  * Copyright (C) 2000 Steinar H. Gunderson
6  *
7  * Large amounts of code adapted from Samba (http://www.samba.org/)
8  * Copyright (C) Andrew Tridgell 1994-1998, and others.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25 /*
26  * This file is probably the most platform-dependent one, and would most
27  * likely be needed to undergo some changes if ported to another OS than
28  * the ones using BSD-style sockets (Winsock is a variant of these,
29  * by the way -- you may only want to change some header files and add some
30  * extra initialization calls).
31  */
32 #include <stdio.h>
33 #include <string.h>
34 #include <stdlib.h>
35 #include <unistd.h>
36 #include <sys/socket.h>
37 #include <sys/time.h>
38 #include <netinet/in.h>
39 #include <arpa/inet.h>
40
41 #include "socket.h"
42 #include "nmb.h"
43 #include "packet.h"
44
45 int open_sockets(void)
46 {
47         unsigned int one = 1;
48         struct sockaddr_in sin;
49         int sock;
50
51         memset((char *)&sin, 0, sizeof(sin));
52         sin.sin_port = htons(137);
53         sin.sin_family = AF_INET;
54         sin.sin_addr.s_addr = INADDR_ANY;
55
56         sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
57         if (sock == -1) {
58                 perror("socket()");
59                 exit(0);
60         }
61
62         setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
63
64         /* bind the socket */
65         if (bind(sock, (struct sockaddr *) &sin,sizeof(sin)) < 0) {
66                 perror("bind()");
67                 exit(1);
68         }
69
70         return sock;
71 }
72
73 int send_packet(struct nmb_packet *nmb, struct in_addr ip, int port, int fd)
74 {
75         char buf[1024];
76         int len = 0;
77
78         memset(buf, 0, sizeof(buf));
79
80         len = build_nmb(buf,nmb);
81         if (!len) return(0);
82
83         return(send_udp(fd,buf,len,ip,port));
84 }
85
86 struct nmb_packet *receive_packet(int fd, int t, struct in_addr *in)
87 {
88         fd_set fds;
89         struct timeval timeout;
90
91         FD_ZERO(&fds);
92         FD_SET(fd,&fds);
93         timeout.tv_sec = t / 1000;
94         timeout.tv_usec = 1000 * (t % 1000);
95
96         select(fd+1,&fds,NULL,NULL,&timeout);
97
98         if (FD_ISSET(fd,&fds))
99                 return read_packet(fd, in);
100
101         return(NULL);
102 }
103
104 struct nmb_packet *read_packet(int fd, struct in_addr *in)
105 {
106         /* extern struct in_addr lastip;
107            extern int lastport; */
108         char buf[MAX_DGRAM_SIZE];
109         int length;
110         int ok = 0;
111         struct nmb_packet *nmb;
112
113         length = read_udp_socket(fd, buf, sizeof(buf), in);
114         if (length < MIN_DGRAM_SIZE) return(NULL);
115
116         nmb = (struct nmb_packet *)malloc(sizeof(struct nmb_packet)); /* ?? */
117         ok = parse_nmb(buf, length, nmb);
118
119         return(nmb);
120 }
121
122 int send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
123 {
124         int ret;
125         struct sockaddr_in sock_out;
126
127         /* set the address and port */
128         memset((char *)&sock_out, 0, sizeof(sock_out));
129         memcpy((char *)&sock_out.sin_addr, (char *)&ip, 4);
130         sock_out.sin_port = htons(port);
131         sock_out.sin_family = AF_INET;
132
133         ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
134                 sizeof(sock_out)) >= 0);
135
136         return ret;
137 }
138
139 ssize_t read_udp_socket(int fd, char *buf, size_t len, struct in_addr *in)
140 {
141         ssize_t ret;
142         struct sockaddr_in sin;
143         int sin_len;
144
145         sin_len = sizeof(sin);
146         memset((char *)&sin, 0, sin_len);
147         ret = (ssize_t)recvfrom(fd, buf, len, 0, (struct sockaddr *)&sin, &sin_len);
148         if (ret <= 0) {
149                 perror("recvfrom()");
150                 return(0);
151         }
152
153         *in = sin.sin_addr;
154
155         return ret;
156 }
157
158