]> git.sur5r.net Git - ngadmin/blob - lib/src/network.c
Code reorganized.
[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  nga->local.sin_family=AF_INET;
15  nga->remote=nga->local;
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 updateTimeout (struct ngadmin *nga) {
74  
75  int ret;
76  
77  
78  // specify receive timeout
79  if ( (ret=setsockopt(nga->sock, SOL_SOCKET, SO_RCVTIMEO, &nga->timeout, sizeof(struct timeval)))<0 ) {
80   perror("setsockopt(SO_RCVTIMEO)");
81   return ret;
82  }
83  
84  
85  return 0;
86  
87 }
88
89
90
91 // --------------------------------------------------------------------------------------------------------------------------
92 int sendNgPacket (struct ngadmin *nga, char code, const struct ether_addr *switch_mac, unsigned int seqnum, const List *attr) {
93  
94  char buffer[1500];
95  struct ng_packet np;
96  ListNode *ln;
97  struct attr *at;
98  int ret;
99  
100  
101  
102  np.buffer=buffer;
103  np.maxlen=sizeof(buffer);
104  initNgPacket(&np);
105  initNgHeader(np.nh, code, &nga->localmac, switch_mac, seqnum);
106  
107  if ( attr!=NULL ) {
108   for (ln=attr->first; ln!=NULL; ln=ln->next) {
109    at=ln->data;
110    addPacketAttr(&np, at->attr, at->size, at->data);
111   }
112  }
113  
114  
115  nga->remote.sin_addr.s_addr=htonl(INADDR_BROADCAST);
116  nga->remote.sin_port=htons(SWITCH_PORT);
117  if ( (ret=sendto(nga->sock, buffer, getPacketTotalSize(&np), 0, (struct sockaddr*)&nga->remote, sizeof(struct sockaddr_in)))<0 ) {
118   perror("sendto");
119  }
120  
121  
122  return ret;
123  
124 }
125
126
127
128 // ---------------------------------------------------------------------------------------------------------------------------------------------------
129 List* recvNgPacket (struct ngadmin *nga, char code, char *error, unsigned short *attr_error, const struct ether_addr *switch_mac, unsigned int seqnum) {
130  
131  char buffer[1500];
132  struct ng_packet np;
133  socklen_t slen=sizeof(struct sockaddr_in);
134  List *l=NULL;
135  int len;
136  
137  
138  np.buffer=buffer;
139  np.maxlen=sizeof(buffer);
140  
141  while ( (len=recvfrom(nga->sock, buffer, sizeof(buffer), 0, (struct sockaddr*)&nga->remote, &slen))>=0 ) {
142   if ( len>=(int)sizeof(struct ng_header) && validateNgHeader(np.nh, code, &nga->localmac, switch_mac, seqnum) ) {
143    initNgPacket(&np);
144    l=extractPacketAttributes(&np, error, attr_error);
145    break;
146   }
147  }
148  
149  
150  return l;
151  
152 }
153
154