List *attr;
int ret = ERR_OK;
struct swi_attr *sa;
+ struct net_conf nc_new;
if (nga == NULL || nc == NULL)
if (sa == NULL)
return ERR_NOTLOG;
+ memcpy(&nc_new, &sa->nc, sizeof(struct net_conf));
+ if (nc->ip.s_addr != 0)
+ nc_new.ip = nc->ip;
+ if (nc->netmask.s_addr != 0)
+ nc_new.netmask = nc->netmask;
+ if (nc->gw.s_addr != 0)
+ nc_new.gw = nc->gw;
+ nc_new.dhcp = nc->dhcp;
+
+ /* gateway must be in the network range */
+ if ((nc_new.ip.s_addr & nc_new.netmask.s_addr) != (nc_new.gw.s_addr & nc_new.netmask.s_addr))
+ return ERR_INVARG;
+
+ /* no need to send anything if old and new configurations are the same */
+ if (memcmp(&nc_new, &sa->nc, sizeof(struct net_conf)) == 0)
+ return ERR_OK;
+
attr = createEmptyList();
- if (nc->dhcp) {
- pushBackList(attr, newShortAttr(ATTR_DHCP, 1));
+ /* Note: DHCP attribute is special, it is 2 two bytes long when sent
+ * by the switch but only 1 byte long when sent by the client
+ */
+ if (nc_new.dhcp) {
+ pushBackList(attr, newByteAttr(ATTR_DHCP, 1));
} else {
- pushBackList(attr, newShortAttr(ATTR_DHCP, 0));
- /* only add non-null values */
- if (nc->ip.s_addr != 0)
- pushBackList(attr, newAddrAttr(ATTR_IP, nc->ip));
- if (nc->netmask.s_addr != 0)
- pushBackList(attr, newAddrAttr(ATTR_NETMASK, nc->netmask));
- if (nc->gw.s_addr != 0)
- pushBackList(attr, newAddrAttr(ATTR_GATEWAY, nc->gw));
+ pushBackList(attr, newAddrAttr(ATTR_IP, nc_new.ip));
+ pushBackList(attr, newAddrAttr(ATTR_NETMASK, nc_new.netmask));
+ pushBackList(attr, newAddrAttr(ATTR_GATEWAY, nc_new.gw));
+ pushBackList(attr, newByteAttr(ATTR_DHCP, 0));
}
ret = writeRequest(nga, attr);
/* update local values */
- sa->nc.dhcp = nc->dhcp;
- if (!nc->dhcp) {
- if (nc->ip.s_addr !=0)
- sa->nc.ip = nc->ip;
- if (nc->netmask.s_addr != 0)
- sa->nc.netmask = nc->netmask;
- if (nc->gw.s_addr != 0)
- sa->nc.gw = nc->gw;
- }
-
+ memcpy(&sa->nc, &nc_new, sizeof(struct net_conf));
end: