Fix compile warnings
[freeradius.git] / src / lib / dhcp.c
index 47e4774..98b8aac 100644 (file)
@@ -244,7 +244,7 @@ RADIUS_PACKET *fr_dhcp_recv(int sockfd)
 
        if (packet->data_len < MIN_PACKET_SIZE) {
                fr_strerror_printf("DHCP packet is too small (%d < %d)",
-                     packet->data_len, MIN_PACKET_SIZE);
+                                  (int) packet->data_len, MIN_PACKET_SIZE);
                rad_free(&packet);
                return NULL;
        }
@@ -746,7 +746,7 @@ int fr_dhcp_decode(RADIUS_PACKET *packet)
                 *      DHCP Opcode is request
                 */
                vp = pairfind(head, 256, DHCP_MAGIC_VENDOR);
-               if (vp && vp->lvalue == 3) {
+               if (vp && vp->vp_integer == 3) {
                        /*
                         *      Vendor is "MSFT 98"
                         */
@@ -757,7 +757,7 @@ int fr_dhcp_decode(RADIUS_PACKET *packet)
                                /*
                                 *      Reply should be broadcast.
                                 */
-                               if (vp) vp->lvalue |= 0x8000;
+                               if (vp) vp->vp_integer |= 0x8000;
                                packet->data[10] |= 0x80;                       
                        }
                }
@@ -1074,6 +1074,16 @@ int fr_dhcp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original)
                                 &packet->dst_ipaddr.ipaddr,
                                 dst_ip_buf, sizeof(dst_ip_buf)),
                       packet->dst_port);
+
+               if (fr_debug_flag) {
+                       for (i = 256; i < 269; i++) {
+                               vp = pairfind(packet->vps, i,
+                                             DHCP_MAGIC_VENDOR);
+                               if (!vp) continue;
+
+                               debug_pair(vp);
+                       }
+               }
        }
 
        p = packet->data;
@@ -1141,14 +1151,25 @@ int fr_dhcp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original)
                }
        }
 
-       if (!original) {
-               *p++ = 1;       /* client message */
+       vp = pairfind(packet->vps, 256, DHCP_MAGIC_VENDOR);
+       if (vp) {
+               *p++ = vp->vp_integer & 0xff;
        } else {
-               *p++ = 2;       /* server message */
+               if (!original) {
+                       *p++ = 1;       /* client message */
+               } else {
+                       *p++ = 2;       /* server message */
+               }
        }
        *p++ = 1;               /* hardware type = ethernet */
        *p++ = 6;               /* 6 bytes of ethernet */
-       *p++ = 0;               /* hops */
+
+       vp = pairfind(packet->vps, 259, DHCP_MAGIC_VENDOR);
+       if (vp) {
+               *p++ = vp->vp_integer & 0xff;
+       } else {
+               *p++ = 0;               /* hops */
+       }
 
        if (original) { /* Xid */
                memcpy(p, original->data + 4, 4);
@@ -1512,4 +1533,46 @@ int fr_dhcp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original)
 
        return 0;
 }
+
+int fr_dhcp_add_arp_entry(int fd, const char *interface,
+                         VALUE_PAIR *macaddr, VALUE_PAIR *ip)
+{
+#ifdef SIOCSARP
+       struct sockaddr_in *sin
+       struct arpreq req;
+
+       if (macaddr->length > sizeof (req.arp_ha.sa_data)) {
+               fr_strerror_printf("ERROR: DHCP only supports up to %d octets for "
+                                  "Client Hardware Address (got %d octets)\n",
+                                  sizeof(req.arp_ha.sa_data),
+                                  macaddr->length);
+               return -1;
+       }
+
+       memset(&req, 0, sizeof(req));
+       sin = (struct sockaddr_in *) &req.arp_pa;
+       sin->sin_family = AF_INET;
+       sin->sin_addr.s_addr = ip->vp_ipaddr;
+       strlcpy(req.arp_dev, interface, sizeof(req.arp_dev));
+       memcpy(&req.arp_ha.sa_data, macaddr->vp_octets, macaddr->length);
+
+       req.arp_flags = ATF_COM;
+       if (ioctl(fd, SIOCSARP, &req) < 0) {
+               fr_strerror_printf("DHCP: Failed to add entry in ARP cache: %s (%d)",
+                                  strerror(errno), errno);
+               return -1;
+       }
+
+       return 0;
+#else
+       fd = fd;                /* -Wunused */
+       interface = interface;  /* -Wunused */
+       macaddr = macaddr;      /* -Wunused */
+       ip = ip;                /* -Wunused */
+
+       fr_strerror_printf("Adding ARP entry is unsupported on this system");
+       return -1;
+#endif
+}
+
 #endif /* WITH_DHCP */