summaryrefslogtreecommitdiffstats
path: root/c/src/libnetworking/rtems
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2000-06-14 17:18:18 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2000-06-14 17:18:18 +0000
commit6f93bb49b4df8f573a8914219841a1d64fde2b6d (patch)
tree222185fa3f33d4bbda5c87ef3e9ed4ae83d61148 /c/src/libnetworking/rtems
parentPatch rtems-rc-20000614-2-cvs.diff from Ralf Corsepius (diff)
downloadrtems-6f93bb49b4df8f573a8914219841a1d64fde2b6d.tar.bz2
Patch from Chris Johns <cjohns@cybertec.com.au> to enhance network
initialization. This adds an interface which makes it easier to control the BSD stack from user code. The BSD stack initialise uses it. It is a sort of `function' interface for an ifconfig command. I also added support for attaching and removing interfaces. With hot swap PCI comming online support for hot swap PCI will be an important factor in "state of art" RTOS's. This is also part of a general move on my part to allow RTEMS to be configured at runtime by calls rather than table driven at initialisation.
Diffstat (limited to 'c/src/libnetworking/rtems')
-rw-r--r--c/src/libnetworking/rtems/rtems_bsdnet.h39
-rw-r--r--c/src/libnetworking/rtems/rtems_glue.c220
2 files changed, 216 insertions, 43 deletions
diff --git a/c/src/libnetworking/rtems/rtems_bsdnet.h b/c/src/libnetworking/rtems/rtems_bsdnet.h
index 5be2e932f9..7838835f0f 100644
--- a/c/src/libnetworking/rtems/rtems_bsdnet.h
+++ b/c/src/libnetworking/rtems/rtems_bsdnet.h
@@ -68,10 +68,17 @@ void rtems_bsdnet_show_tcp_stats (void);
*/
struct rtems_bsdnet_ifconfig {
/*
- * These two entries must be supplied for each interface.
+ * These three entries must be supplied for each interface.
*/
char *name;
- int (*attach)(struct rtems_bsdnet_ifconfig *conf);
+
+ /*
+ * This function now handles attaching and detaching an interface.
+ * The parameter attaching indicates the operation being invoked.
+ * For older attach functions which do not have the extra parameter
+ * it will be ignored.
+ */
+ int (*attach)(struct rtems_bsdnet_ifconfig *conf, int attaching);
/*
* Link to next interface
@@ -132,8 +139,36 @@ struct rtems_bsdnet_config {
char *name_server[3]; /* BOOTP */
char *ntp_server[3]; /* BOOTP */
};
+
+/*
+ * Default global device configuration structure. This is scanned
+ * by the initialize network function. Check the network demo's for
+ * an example of the structure. Like the RTEMS configuration tables,
+ * they are not part of RTEMS but part of your application or bsp
+ * code.
+ */
extern struct rtems_bsdnet_config rtems_bsdnet_config;
+
+/*
+ * Initialise the BSD stack, attach and `up' interfaces
+ * in the `rtems_bsdnet_config'. RTEMS must already be initialised.
+ */
int rtems_bsdnet_initialize_network (void);
+
+/*
+ * Dynamic interface control. Drivers must free any resources such as
+ * memory, interrupts, io regions claimed during the `attach' and/or
+ * `up' operations when asked to `detach'.
+ * You must configure the interface after attaching it.
+ */
+void rtems_bsdnet_attach (struct rtems_bsdnet_ifconfig *ifconfig);
+void rtems_bsdnet_detach (struct rtems_bsdnet_ifconfig *ifconfig);
+
+/*
+ * Interface configuration. The commands are listed in `sys/sockio.h'.
+ */
+int rtems_bsdnet_ifconfig (const char *ifname, unsigned32 cmd, void *param);
+
void rtems_bsdnet_do_bootp (void);
int rtems_bsdnet_synchronize_ntp (int interval, rtems_task_priority priority);
diff --git a/c/src/libnetworking/rtems/rtems_glue.c b/c/src/libnetworking/rtems/rtems_glue.c
index 4213b91a2c..31b44a6656 100644
--- a/c/src/libnetworking/rtems/rtems_glue.c
+++ b/c/src/libnetworking/rtems/rtems_glue.c
@@ -738,8 +738,7 @@ static int
rtems_bsdnet_setup (void)
{
struct rtems_bsdnet_ifconfig *ifp;
- int s;
- struct ifreq ifreq;
+ short flags;
struct sockaddr_in address;
struct sockaddr_in netmask;
struct sockaddr_in broadcast;
@@ -777,31 +776,17 @@ rtems_bsdnet_setup (void)
/*
* Configure interfaces
*/
- s = socket (AF_INET, SOCK_DGRAM, 0);
- if (s < 0) {
- printf ("Can't create initial socket: %s\n", strerror (errno));
- return -1;
- }
for (ifp = rtems_bsdnet_config.ifconfig ; ifp ; ifp = ifp->next) {
if (ifp->ip_address == NULL)
continue;
/*
- * Get the interface flags
- */
- strcpy (ifreq.ifr_name, ifp->name);
- if (ioctl (s, SIOCGIFFLAGS, &ifreq) < 0) {
- printf ("Can't get %s flags: %s\n", ifp->name, strerror (errno));
- return -1;
- }
-
- /*
* Bring interface up
*/
- ifreq.ifr_flags |= IFF_UP;
- if (ioctl (s, SIOCSIFFLAGS, &ifreq) < 0) {
+ flags = IFF_UP;
+ if (rtems_bsdnet_ifconfig (ifp->name, SIOCSIFFLAGS, &flags) < 0) {
printf ("Can't bring %s up: %s\n", ifp->name, strerror (errno));
- return -1;
+ continue;
}
/*
@@ -811,10 +796,9 @@ rtems_bsdnet_setup (void)
netmask.sin_len = sizeof netmask;
netmask.sin_family = AF_INET;
netmask.sin_addr.s_addr = inet_addr (ifp->ip_netmask);
- memcpy (&ifreq.ifr_addr, &netmask, sizeof netmask);
- if (ioctl (s, SIOCSIFNETMASK, &ifreq) < 0) {
+ if (rtems_bsdnet_ifconfig (ifp->name, SIOCSIFNETMASK, &netmask) < 0) {
printf ("Can't set %s netmask: %s\n", ifp->name, strerror (errno));
- return -1;
+ continue;
}
/*
@@ -824,30 +808,35 @@ rtems_bsdnet_setup (void)
address.sin_len = sizeof address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr (ifp->ip_address);
- memcpy (&ifreq.ifr_addr, &address, sizeof address);
- if (ioctl (s, SIOCSIFADDR, &ifreq) < 0) {
+ if (rtems_bsdnet_ifconfig (ifp->name, SIOCSIFADDR, &address) < 0) {
printf ("Can't set %s address: %s\n", ifp->name, strerror (errno));
- return -1;
+ continue;
}
/*
- * Set interface broadcast address
+ * Set interface broadcast address if the interface has the
+ * broadcast flag set.
*/
- memset (&broadcast, '\0', sizeof broadcast);
- broadcast.sin_len = sizeof broadcast;
- broadcast.sin_family = AF_INET;
- broadcast.sin_addr.s_addr = address.sin_addr.s_addr | ~netmask.sin_addr.s_addr;
- memcpy (&ifreq.ifr_broadaddr, &broadcast, sizeof broadcast);
- if (ioctl (s, SIOCSIFBRDADDR, &ifreq) < 0)
- printf ("Can't set %s broadcast address: %s\n", ifp->name, strerror (errno));
+ if (rtems_bsdnet_ifconfig (ifp->name, SIOCGIFFLAGS, &flags) < 0) {
+ printf ("Can't read %s flags: %s\n", ifp->name, strerror (errno));
+ continue;
+ }
+ if (flags & IFF_BROADCAST) {
+ memset (&broadcast, '\0', sizeof broadcast);
+ broadcast.sin_len = sizeof broadcast;
+ broadcast.sin_family = AF_INET;
+ broadcast.sin_addr.s_addr =
+ address.sin_addr.s_addr | ~netmask.sin_addr.s_addr;
+ if (rtems_bsdnet_ifconfig (ifp->name, SIOCSIFBRDADDR, &broadcast) < 0) {
+ struct in_addr in_addr;
+ in_addr.s_addr = broadcast.sin_addr.s_addr;
+ printf ("Can't set %s broadcast address %s: %s\n",
+ ifp->name, inet_ntoa (in_addr), strerror (errno));
+ }
+ }
}
/*
- * We're done with the dummy socket
- */
- close (s);
-
- /*
* Set default route
*/
if (rtems_bsdnet_config.gateway) {
@@ -889,9 +878,7 @@ rtems_bsdnet_initialize_network (void)
* Attach interfaces
*/
for (ifp = rtems_bsdnet_config.ifconfig ; ifp ; ifp = ifp->next) {
- rtems_bsdnet_semaphore_obtain ();
- (ifp->attach)(ifp);
- rtems_bsdnet_semaphore_release ();
+ rtems_bsdnet_attach (ifp);
}
/*
@@ -905,6 +892,157 @@ rtems_bsdnet_initialize_network (void)
}
/*
+ * Attach a network interface.
+ */
+void rtems_bsdnet_attach (struct rtems_bsdnet_ifconfig *ifp)
+{
+ if (ifp) {
+ rtems_bsdnet_semaphore_obtain ();
+ (ifp->attach)(ifp, 1);
+ rtems_bsdnet_semaphore_release ();
+ }
+}
+
+/*
+ * Detach a network interface.
+ */
+void rtems_bsdnet_detach (struct rtems_bsdnet_ifconfig *ifp)
+{
+ if (ifp) {
+ rtems_bsdnet_semaphore_obtain ();
+ (ifp->attach)(ifp, 0);
+ rtems_bsdnet_semaphore_release ();
+ }
+}
+
+/*
+ * Interface Configuration.
+ */
+int rtems_bsdnet_ifconfig (const char *ifname, unsigned32 cmd, void *param)
+{
+ int s, r = 0;
+ struct ifreq ifreq;
+
+ /*
+ * Configure interfaces
+ */
+ s = socket (AF_INET, SOCK_DGRAM, 0);
+ if (s < 0)
+ return -1;
+
+ strncpy (ifreq.ifr_name, ifname, IFNAMSIZ);
+
+ rtems_bsdnet_semaphore_obtain ();
+
+ switch (cmd) {
+ case SIOCSIFADDR:
+ case SIOCSIFNETMASK:
+ memcpy (&ifreq.ifr_addr, param, sizeof (struct sockaddr));
+ r = ioctl (s, cmd, &ifreq);
+ break;
+
+ case OSIOCGIFADDR:
+ case SIOCGIFADDR:
+ case OSIOCGIFNETMASK:
+ case SIOCGIFNETMASK:
+ if ((r = ioctl (s, cmd, &ifreq)) < 0)
+ break;
+ memcpy (param, &ifreq.ifr_addr, sizeof (struct sockaddr));
+ break;
+
+ case SIOCGIFFLAGS:
+ case SIOCSIFFLAGS:
+ if ((r = ioctl (s, SIOCGIFFLAGS, &ifreq)) < 0)
+ break;
+ if (cmd == SIOCGIFFLAGS) {
+ *((short*) param) = ifreq.ifr_flags;
+ break;
+ }
+ ifreq.ifr_flags |= *((short*) param);
+ r = ioctl (s, SIOCSIFFLAGS, &ifreq);
+ break;
+
+ case SIOCSIFDSTADDR:
+ memcpy (&ifreq.ifr_dstaddr, param, sizeof (struct sockaddr));
+ r = ioctl (s, cmd, &ifreq);
+ break;
+
+ case OSIOCGIFDSTADDR:
+ case SIOCGIFDSTADDR:
+ if ((r = ioctl (s, cmd, &ifreq)) < 0)
+ break;
+ memcpy (param, &ifreq.ifr_dstaddr, sizeof (struct sockaddr));
+ break;
+
+ case SIOCSIFBRDADDR:
+ memcpy (&ifreq.ifr_broadaddr, param, sizeof (struct sockaddr));
+ r = ioctl (s, cmd, &ifreq);
+ break;
+
+ case OSIOCGIFBRDADDR:
+ case SIOCGIFBRDADDR:
+ if ((r = ioctl (s, cmd, &ifreq)) < 0)
+ break;
+ memcpy (param, &ifreq.ifr_broadaddr, sizeof (struct sockaddr));
+ break;
+
+ case SIOCSIFMETRIC:
+ ifreq.ifr_metric = *((int*) param);
+ r = ioctl (s, cmd, &ifreq);
+ break;
+
+ case SIOCGIFMETRIC:
+ if ((r = ioctl (s, cmd, &ifreq)) < 0)
+ break;
+ *((int*) param) = ifreq.ifr_metric;
+ break;
+
+ case SIOCSIFMTU:
+ ifreq.ifr_mtu = *((int*) param);
+ r = ioctl (s, cmd, &ifreq);
+ break;
+
+ case SIOCGIFMTU:
+ if ((r = ioctl (s, cmd, &ifreq)) < 0)
+ break;
+ *((int*) param) = ifreq.ifr_mtu;
+ break;
+
+ case SIOCSIFPHYS:
+ ifreq.ifr_phys = *((int*) param);
+ r = ioctl (s, cmd, &ifreq);
+ break;
+
+ case SIOCGIFPHYS:
+ if ((r = ioctl (s, cmd, &ifreq)) < 0)
+ break;
+ *((int*) param) = ifreq.ifr_phys;
+ break;
+
+ case SIOCSIFMEDIA:
+ ifreq.ifr_media = *((int*) param);
+ r = ioctl (s, cmd, &ifreq);
+ break;
+
+ case SIOCGIFMEDIA:
+ if ((r = ioctl (s, cmd, &ifreq)) < 0)
+ break;
+ *((int*) param) = ifreq.ifr_media;
+ break;
+
+ default:
+ errno = EOPNOTSUPP;
+ r = -1;
+ break;
+ }
+
+ rtems_bsdnet_semaphore_release ();
+
+ close (s);
+ return r;
+}
+
+/*
* Parse a network driver name into a name and a unit number
*/
int