]> git.sur5r.net Git - ngadmin/blob - lib/src/network.c
cf293d0360ef0fa6c46f5889ef70bc00d7b0cda8
[ngadmin] / lib / src / network.c
1
2 #include "network.h"
3
4
5
6
7 // -----------------------------------
8 int startNetwork (struct ngadmin *nga) {
9  
10  struct ifreq ifr;
11  int ret;
12  
13  
14  memset(&nga->local, 0, sizeof(struct sockaddr_in));
15  nga->local.sin_family=AF_INET;
16  nga->local.sin_port=htons(CLIENT_PORT);
17  
18  memset(&ifr, 0, sizeof(struct ifreq));
19  strncpy(ifr.ifr_name, nga->iface, IFNAMSIZ-1);
20  
21  if ( (nga->sock=socket(AF_INET, SOCK_DGRAM, 0))<0 ) {
22   perror("socket");
23   return nga->sock;
24  }
25  
26  // get the interface IP address
27  if ( (ret=ioctl(nga->sock, SIOCGIFADDR, &ifr))<0 ) {
28   perror("ioctl(SIOCGIFADDR)");
29   close(nga->sock);
30   return ret;
31  }
32  //local.sin_addr=(*(struct sockaddr_in*)&ifr.ifr_addr).sin_addr; // FIXME
33  
34  // get the interface MAC address
35  if ( (ret=ioctl(nga->sock, SIOCGIFHWADDR, &ifr))<0 ) {
36   perror("ioctl(SIOCGIFHWADDR)");
37   close(nga->sock);
38   return ret;
39  }
40  memcpy(&nga->localmac, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
41  
42  // bind
43  if ( (ret=bind(nga->sock, (struct sockaddr*)&nga->local, sizeof(struct sockaddr_in)))<0 ) {
44   perror("bind");
45   close(nga->sock);
46   return ret;
47  }
48  
49  // allow broadcasting
50  ret=1;
51  if ( (ret=setsockopt(nga->sock, SOL_SOCKET, SO_BROADCAST, &ret, sizeof(ret)))<0 ) {
52   perror("setsockopt(SO_BROADCAST)");
53   return ret;
54  }
55  
56  
57  return 0;
58  
59 }
60
61
62
63 // ----------------------------------
64 int stopNetwork (struct ngadmin *nga) {
65  
66  return close(nga->sock);
67  
68 }
69
70
71
72 // -------------------------------------
73 int forceInterface (struct ngadmin *nga) {
74  
75  int ret;
76  
77  
78  
79  ret=1;
80  if ( (ret=setsockopt(nga->sock, SOL_SOCKET, SO_BINDTODEVICE, nga->iface, strlen(nga->iface)+1))<0 ) {
81   perror("setsockopt(SO_BINDTODEVICE)");
82   return ret;
83  }
84  
85  ret=1;
86  if ( (ret=setsockopt(nga->sock, SOL_SOCKET, SO_DONTROUTE, &ret, sizeof(ret)))<0 ) {
87   perror("setsockopt(SO_DONTROUTE)");
88   return ret;
89  }
90  
91  
92  return 0;
93  
94 }
95
96
97
98 // ------------------------------------
99 int updateTimeout (struct ngadmin *nga) {
100  
101  int ret;
102  
103  
104  // specify receive timeout
105  if ( (ret=setsockopt(nga->sock, SOL_SOCKET, SO_RCVTIMEO, &nga->timeout, sizeof(struct timeval)))<0 ) {
106   perror("setsockopt(SO_RCVTIMEO)");
107   return ret;
108  }
109  
110  
111  return 0;
112  
113 }
114
115
116
117 // ----------------------------------------------------------------
118 int sendNgPacket (struct ngadmin *nga, char code, const List *attr) {
119  
120  char buffer[1500];
121  struct ng_packet np;
122  ListNode *ln;
123  struct attr *at;
124  struct sockaddr_in remote;
125  const struct swi_attr *sa=nga->current;
126  int ret;
127  
128  
129  
130  np.buffer=buffer;
131  np.maxlen=sizeof(buffer);
132  initNgPacket(&np);
133  initNgHeader(np.nh, code, &nga->localmac, sa==NULL ? &nullMac : &sa->mac , ++nga->seq);
134  
135  if ( attr!=NULL ) {
136   for (ln=attr->first; ln!=NULL; ln=ln->next) {
137    at=ln->data;
138    addPacketAttr(&np, at->attr, at->size, at->data);
139   }
140  }
141  
142  memset(&remote, 0, sizeof(struct sockaddr_in));
143  remote.sin_family=AF_INET;
144  remote.sin_addr.s_addr= sa==NULL || nga->keepbroad ? htonl(INADDR_BROADCAST) : sa->nc.ip.s_addr ;
145  remote.sin_port=htons(SWITCH_PORT);
146  
147  if ( (ret=sendto(nga->sock, buffer, getPacketTotalSize(&np), 0, (struct sockaddr*)&remote, sizeof(struct sockaddr_in)))<0 ) {
148   perror("sendto");
149  }
150  
151  
152  return ret;
153  
154 }
155
156
157
158 // -----------------------------------------------------------------------------------------
159 List* recvNgPacket (struct ngadmin *nga, char code, char *error, unsigned short *attr_error) {
160  
161  char buffer[1500];
162  struct ng_packet np;
163  struct sockaddr_in remote;
164  socklen_t slen=sizeof(struct sockaddr_in);
165  const struct swi_attr *sa=nga->current;
166  List *l=NULL;
167  int len;
168  
169  
170  np.buffer=buffer;
171  np.maxlen=sizeof(buffer);
172  
173  memset(&remote, 0, sizeof(struct sockaddr_in));
174  remote.sin_family=AF_INET;
175  
176  while ( (len=recvfrom(nga->sock, buffer, sizeof(buffer), 0, (struct sockaddr*)&remote, &slen))>=0 ) {
177   if ( ntohs(remote.sin_port)==SWITCH_PORT && len>=(int)sizeof(struct ng_header) && validateNgHeader(np.nh, code, &nga->localmac, sa==NULL ? NULL : &sa->mac , nga->seq) ) {
178    initNgPacket(&np);
179    l=extractPacketAttributes(&np, error, attr_error);
180    break;
181   }
182  }
183  
184  
185  return l;
186  
187 }
188
189