]> git.sur5r.net Git - ngadmin/blob - raw/src/net.c
cc619efdd94b8fe51334ffffd97c6a61318cd711
[ngadmin] / raw / src / net.c
1
2 #include <stdio.h>
3 #include <errno.h>
4
5 #include <nsdp/net.h>
6 #include "encoding.h"
7
8
9 int sendNsdpPacket (int sock, const struct nsdp_cmd *nc, const List *attr)
10 {
11         unsigned char buffer[1500];
12         struct nsdp_packet np;
13         int ret;
14         
15         
16         if (sock < 0 || nc == NULL)
17                 return -EINVAL;
18         
19         np.buffer = buffer;
20         np.maxlen = sizeof(buffer);
21         initNsdpPacket(&np);
22         initNsdpHeader(np.nh, nc);
23         
24         ret = addPacketAttributes(&np, attr, nc->ports);
25         if (ret < 0)
26                 return ret;
27         
28         ret = sendto(sock, buffer, getPacketTotalSize(&np), 0, (struct sockaddr*)&nc->remote_addr, sizeof(struct sockaddr_in));
29         if (ret < 0)
30                 perror("sendto");
31         
32         
33         return ret;
34 }
35
36
37 int recvNsdpPacket (int sock, struct nsdp_cmd *nc, List *attr, const struct timeval *timeout)
38 {
39         unsigned char buffer[1500];
40         struct nsdp_packet np;
41         socklen_t slen = sizeof(struct sockaddr_in);
42         struct timeval rem;
43         fd_set fs;
44         int len = -1;
45         struct sockaddr_in remote;
46         
47         
48         if (sock < 0 || nc == NULL || attr == NULL)
49                 return -EINVAL;
50         
51         np.buffer = buffer;
52         
53         if (timeout != NULL)
54                 rem = *timeout;
55         
56         memset(&remote, 0, sizeof(struct sockaddr_in));
57         remote.sin_family = AF_INET;
58         
59         while (1) {
60                 FD_ZERO(&fs);
61                 FD_SET(sock, &fs);
62                 select(sock + 1, &fs, NULL, NULL, timeout == NULL ? NULL : &rem); /* FIXME: non portable */
63                 
64                 len = recvfrom(sock, buffer, sizeof(buffer), MSG_DONTWAIT, (struct sockaddr*)&remote, &slen);
65                 if (len < 0)
66                         break;
67                 
68                 np.maxlen = len;
69                 initNsdpPacket(&np);
70                 
71                 if ((nc->remote_addr.sin_addr.s_addr != 0 && remote.sin_addr.s_addr != nc->remote_addr.sin_addr.s_addr) ||
72                     (nc->remote_addr.sin_port != 0 && remote.sin_port != nc->remote_addr.sin_port) ||
73                     len < (int)sizeof(struct nsdp_header) ||
74                     !validateNsdpHeader(np.nh, nc) ||
75                     extractPacketAttributes(&np, attr, nc->ports) < 0)
76                         continue;
77                 
78                 nc->remote_addr = remote;
79                 
80                 nc->code = np.nh->code;
81                 nc->error = np.nh->error;
82                 nc->attr_error = ntohs(np.nh->attr);
83                 
84                 len = 0;
85                 break;
86         }
87         
88         
89         return len;
90 }
91
92