source: rtems-libbsd/freebsd-userspace/rtems/rtems-net-setup.c @ 0d928a0

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 0d928a0 was bd6dd6e, checked in by Joel Sherrill <joel.sherrill@…>, on 07/27/12 at 12:45:06

net-setup: Add routing and old stack's configuration

This allows the old stack's configuration structures to be used
unchanged even though this code currently does not support all
of the options. It likely will never support all of the options
as some should eventually come through configuration files as
they would in a real FreeBSD system. Other configuration
parameters are likely configurable via "hints".

  • Property mode set to 100644
File size: 7.1 KB
RevLine 
[e25eda8]1/*
2 * XXX copyright and license.
3 * XXX integrate more setup from old code in rtems_glue.c
4 * XXX integrate using old configuration structure as it makes sense
5 */
6
7#include <freebsd/bsd.h>
8#include <sys/socket.h>
9#include <net/if.h>
10#include <netinet/in.h>
11#include <arpa/inet.h>
[bd6dd6e]12#include <net/route.h>
13#include <rtems/rtems_bsdnet.h>
[e25eda8]14
15static const struct sockaddr_in address_template = {
16  sizeof(address_template),
17  AF_INET,
18  0,
19  { INADDR_ANY },
20  { 0, 0, 0, 0, 0, 0, 0, 0 }
21};
22
[bd6dd6e]23/*
24 * Manipulate routing tables
25 */
26int rtems_bsdnet_rtrequest(
27  int              req,
28  struct sockaddr *dst,
29  struct sockaddr *gateway,
30  struct sockaddr *netmask,
31  int              flags,
32  struct rtentry **net_nrt
33)
34{
35  int error;
36
37  // rtems_bsdnet_semaphore_obtain();
38  error = rtrequest(req, dst, gateway, netmask, flags, net_nrt);
39  // rtems_bsdnet_semaphore_release();
40  if (error) {
41    errno = error;
42    return -1;
43  }
44  return 0;
45}
46
[e25eda8]47static void
48rtems_bsdnet_initialize_sockaddr_in(struct sockaddr_in *addr)
49{
50  memcpy(addr, &address_template, sizeof(*addr));
51}
52
53/*
54 * Interface Configuration.
55 */
56int rtems_bsdnet_ifconfig(const char *ifname, uint32_t cmd, void *param)
57{
58  int s, r = 0;
59  struct ifreq ifreq;
60
61  /*
62   * Configure interfaces
63   */
[bd6dd6e]64  s = socket(AF_INET, SOCK_DGRAM, 0);
[e25eda8]65  if (s < 0)
66    return -1;
67
[bd6dd6e]68  strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);
[e25eda8]69
70  switch (cmd) {
71    case SIOCSIFADDR:
72    case SIOCSIFNETMASK:
[bd6dd6e]73      memcpy(&ifreq.ifr_addr, param, sizeof(struct sockaddr));
74      r = ioctl(s, cmd, &ifreq);
[e25eda8]75      break;
76
77    case OSIOCGIFADDR:
78    case SIOCGIFADDR:
79    case OSIOCGIFNETMASK:
80    case SIOCGIFNETMASK:
[bd6dd6e]81      if ((r = ioctl(s, cmd, &ifreq)) < 0)
[e25eda8]82        break;
[bd6dd6e]83      memcpy(param, &ifreq.ifr_addr, sizeof(struct sockaddr));
[e25eda8]84      break;
85
86    case SIOCGIFFLAGS:
87    case SIOCSIFFLAGS:
[bd6dd6e]88      if ((r = ioctl(s, SIOCGIFFLAGS, &ifreq)) < 0)
[e25eda8]89        break;
90      if (cmd == SIOCGIFFLAGS) {
91        *((short*) param) = ifreq.ifr_flags;
92        break;
93      }
94      ifreq.ifr_flags |= *((short*) param);
95      if ( (*((short*) param) & IFF_UP ) == 0 ) {
96          /* set the interface down */
97          ifreq.ifr_flags &= ~(IFF_UP);
98      }
[bd6dd6e]99      r = ioctl(s, SIOCSIFFLAGS, &ifreq);
[e25eda8]100      break;
101
102    case SIOCSIFDSTADDR:
[bd6dd6e]103      memcpy(&ifreq.ifr_dstaddr, param, sizeof(struct sockaddr));
104      r = ioctl(s, cmd, &ifreq);
[e25eda8]105      break;
106
107    case OSIOCGIFDSTADDR:
108    case SIOCGIFDSTADDR:
[bd6dd6e]109      if ((r = ioctl(s, cmd, &ifreq)) < 0)
[e25eda8]110        break;
[bd6dd6e]111      memcpy(param, &ifreq.ifr_dstaddr, sizeof(struct sockaddr));
[e25eda8]112      break;
113
114    case SIOCSIFBRDADDR:
[bd6dd6e]115      memcpy(&ifreq.ifr_broadaddr, param, sizeof(struct sockaddr));
116      r = ioctl(s, cmd, &ifreq);
[e25eda8]117      break;
118
119    case OSIOCGIFBRDADDR:
120    case SIOCGIFBRDADDR:
[bd6dd6e]121      if ((r = ioctl(s, cmd, &ifreq)) < 0)
[e25eda8]122        break;
[bd6dd6e]123      memcpy(param, &ifreq.ifr_broadaddr, sizeof(struct sockaddr));
[e25eda8]124      break;
125
126    case SIOCSIFMETRIC:
127      ifreq.ifr_metric = *((int*) param);
[bd6dd6e]128      r = ioctl(s, cmd, &ifreq);
[e25eda8]129      break;
130
131    case SIOCGIFMETRIC:
[bd6dd6e]132      if ((r = ioctl(s, cmd, &ifreq)) < 0)
[e25eda8]133        break;
134      *((int*) param) = ifreq.ifr_metric;
135      break;
136
137    case SIOCSIFMTU:
138      ifreq.ifr_mtu = *((int*) param);
[bd6dd6e]139      r = ioctl(s, cmd, &ifreq);
[e25eda8]140      break;
141
142    case SIOCGIFMTU:
[bd6dd6e]143      if ((r = ioctl(s, cmd, &ifreq)) < 0)
[e25eda8]144        break;
145      *((int*) param) = ifreq.ifr_mtu;
146      break;
147
148    case SIOCSIFPHYS:
149      ifreq.ifr_phys = *((int*) param);
[bd6dd6e]150      r = ioctl(s, cmd, &ifreq);
[e25eda8]151      break;
152
153    case SIOCGIFPHYS:
[bd6dd6e]154      if ((r = ioctl(s, cmd, &ifreq)) < 0)
[e25eda8]155        break;
156      *((int*) param) = ifreq.ifr_phys;
157      break;
158
159    case SIOCSIFMEDIA:
160      ifreq.ifr_media = *((int*) param);
[bd6dd6e]161      r = ioctl(s, cmd, &ifreq);
[e25eda8]162      break;
163
164    case SIOCGIFMEDIA:
165      /* 'param' passes the phy index they want to
166       * look at...
167       */
168      ifreq.ifr_media = *((int*) param);
[bd6dd6e]169      if ((r = ioctl(s, cmd, &ifreq)) < 0)
[e25eda8]170        break;
171      *((int*) param) = ifreq.ifr_media;
172      break;
173
174    case SIOCAIFADDR:
175    case SIOCDIFADDR:
176      r = ioctl(s, cmd, (struct ifreq *) param);
177      break;
178
179    default:
180      errno = EOPNOTSUPP;
181      r = -1;
182      break;
183  }
184
[bd6dd6e]185  close(s);
[e25eda8]186  return r;
187}
188
189
190
191static bool rtems_bsdnet_setup_interface(
192  const char *name,
193  const char *ip_address,
194  const char *ip_netmask
195)
196{
197  struct sockaddr_in address;
198  struct sockaddr_in netmask;
199  short flags;
200
201  /*
202   * Bring interface up
203   */
204  flags = IFF_UP;
[bd6dd6e]205  if (rtems_bsdnet_ifconfig(name, SIOCSIFFLAGS, &flags) < 0) {
206    printf("Can't bring %s up: %s\n", name, strerror(errno));
[e25eda8]207    return false;
208  }
209
210  /*
211   * Set interface netmask
212   */
213  rtems_bsdnet_initialize_sockaddr_in(&netmask);
[bd6dd6e]214  netmask.sin_addr.s_addr = inet_addr(ip_netmask);
215  if (rtems_bsdnet_ifconfig(name, SIOCSIFNETMASK, &netmask) < 0) {
216    printf("Can't set %s netmask: %s\n", name, strerror(errno));
[e25eda8]217    return false;
218  }
219
220  /*
221   * Set interface address
222   */
223  rtems_bsdnet_initialize_sockaddr_in(&address);
[bd6dd6e]224  address.sin_addr.s_addr = inet_addr(ip_address);
225  if (rtems_bsdnet_ifconfig(name, SIOCSIFADDR, &address) < 0) {
226    printf("Can't set %s address: %s\n", name, strerror(errno));
[e25eda8]227    return false;
228  }
229
230  /*
231   * Set interface broadcast address if the interface has the
232   * broadcast flag set.
233   */
[bd6dd6e]234  if (rtems_bsdnet_ifconfig(name, SIOCGIFFLAGS, &flags) < 0) {
235    printf("Can't read %s flags: %s\n", name, strerror(errno));
[e25eda8]236    return false;
237  }
238
239  if (flags & IFF_BROADCAST) {
240    struct sockaddr_in broadcast;
241
242    rtems_bsdnet_initialize_sockaddr_in(&broadcast);
243    broadcast.sin_addr.s_addr =
244        address.sin_addr.s_addr | ~netmask.sin_addr.s_addr;
[bd6dd6e]245    if (rtems_bsdnet_ifconfig(name, SIOCSIFBRDADDR, &broadcast) < 0) {
[e25eda8]246      struct in_addr  in_addr;
247      char      buf[20];
248      in_addr.s_addr = broadcast.sin_addr.s_addr;
249      if (!inet_ntop(AF_INET, &in_addr, buf, sizeof(buf)))
250          strcpy(buf,"?.?.?.?");
[bd6dd6e]251      printf("Can't set %s broadcast address %s: %s\n",
252        name, buf, strerror(errno));
[e25eda8]253    }
254  }
255
256  return true;
257}
258
259
260
261void rtems_initialize_interfaces(void)
262{
[bd6dd6e]263  bool                          any_if_configured;
264  struct rtems_bsdnet_ifconfig *ifp;
[e25eda8]265
266  any_if_configured = false;
267
268  any_if_configured |= rtems_bsdnet_setup_interface(
269    "lo0",
270    "127.0.0.1",
271    "255.0.0.0"
272  );
273
274
275  for (ifp = rtems_bsdnet_config.ifconfig ; ifp ; ifp = ifp->next) {
276    if (ifp->ip_address == NULL)
277      continue;
278
279    any_if_configured |= rtems_bsdnet_setup_interface(
280      ifp->name,
281      ifp->ip_address,
282      ifp->ip_netmask
283    );
284  }
[bd6dd6e]285  /*
286   * Set default route
287   */
288  if (rtems_bsdnet_config.gateway && any_if_configured) {
289    struct sockaddr_in address;
290    struct sockaddr_in netmask;
291    struct sockaddr_in gateway;
292
293    rtems_bsdnet_initialize_sockaddr_in(&address);
294    rtems_bsdnet_initialize_sockaddr_in(&netmask);
295    rtems_bsdnet_initialize_sockaddr_in(&gateway);
296
297    gateway.sin_addr.s_addr = inet_addr (rtems_bsdnet_config.gateway);
298
299    if (rtems_bsdnet_rtrequest (
300        RTM_ADD,
301        (struct sockaddr *)&address,
302        (struct sockaddr *)&gateway,
303        (struct sockaddr *)&netmask,
304        (RTF_UP | RTF_GATEWAY | RTF_STATIC), NULL) < 0) {
305      printf ("Can't set default route: %s\n", strerror (errno));
306      return -1;
307    }
308  }
309  return 0;
[e25eda8]310
311}
Note: See TracBrowser for help on using the repository browser.