Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/networking/udhcp/packet.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 1  Line 1 
1  /* vi: set sw=4 ts=4: */  /* vi: set sw=4 ts=4: */
2    /*
3     * packet.c -- packet ops
4     * Rewrite by Russ Dill <Russ.Dill@asu.edu> July 2001
5     *
6     * Licensed under GPLv2, see file LICENSE in this tarball for details.
7     */
8  #include <netinet/in.h>  #include <netinet/in.h>
9  #if (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1) || defined _NEWLIB_VERSION  #if (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1) || defined _NEWLIB_VERSION
10  #include <netpacket/packet.h>  #include <netpacket/packet.h>
# Line 14  Line 19 
19  #include "dhcpd.h"  #include "dhcpd.h"
20  #include "options.h"  #include "options.h"
21    
22    void FAST_FUNC udhcp_init_header(struct dhcp_packet *packet, char type)
 void FAST_FUNC udhcp_init_header(struct dhcpMessage *packet, char type)  
23  {  {
24   memset(packet, 0, sizeof(struct dhcpMessage));   memset(packet, 0, sizeof(struct dhcp_packet));
25   packet->op = BOOTREQUEST; /* if client to a server */   packet->op = BOOTREQUEST; /* if client to a server */
26   switch (type) {   switch (type) {
27   case DHCPOFFER:   case DHCPOFFER:
# Line 32  void FAST_FUNC udhcp_init_header(struct Line 36  void FAST_FUNC udhcp_init_header(struct
36   add_simple_option(packet->options, DHCP_MESSAGE_TYPE, type);   add_simple_option(packet->options, DHCP_MESSAGE_TYPE, type);
37  }  }
38    
39    #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2
40    void FAST_FUNC udhcp_dump_packet(struct dhcp_packet *packet)
41    {
42     char buf[sizeof(packet->chaddr)*2 + 1];
43    
44     if (dhcp_verbose < 2)
45     return;
46    
47     bb_info_msg(
48     //" op %x"
49     //" htype %x"
50     " hlen %x"
51     //" hops %x"
52     " xid %x"
53     //" secs %x"
54     //" flags %x"
55     " ciaddr %x"
56     " yiaddr %x"
57     " siaddr %x"
58     " giaddr %x"
59     //" chaddr %s"
60     //" sname %s"
61     //" file %s"
62     //" cookie %x"
63     //" options %s"
64     //, packet->op
65     //, packet->htype
66     , packet->hlen
67     //, packet->hops
68     , packet->xid
69     //, packet->secs
70     //, packet->flags
71     , packet->ciaddr
72     , packet->yiaddr
73     , packet->siaddr_nip
74     , packet->gateway_nip
75     //, packet->chaddr[16]
76     //, packet->sname[64]
77     //, packet->file[128]
78     //, packet->cookie
79     //, packet->options[]
80     );
81     *bin2hex(buf, (void *) packet->chaddr, sizeof(packet->chaddr)) = '\0';
82     bb_info_msg(" chaddr %s", buf);
83    }
84    #endif
85    
86  /* read a packet from socket fd, return -1 on read error, -2 on packet error */  /* Read a packet from socket fd, return -1 on read error, -2 on packet error */
87  int FAST_FUNC udhcp_recv_kernel_packet(struct dhcpMessage *packet, int fd)  int FAST_FUNC udhcp_recv_kernel_packet(struct dhcp_packet *packet, int fd)
88  {  {
89   int bytes;   int bytes;
90   unsigned char *vendor;   unsigned char *vendor;
# Line 42  int FAST_FUNC udhcp_recv_kernel_packet(s Line 92  int FAST_FUNC udhcp_recv_kernel_packet(s
92   memset(packet, 0, sizeof(*packet));   memset(packet, 0, sizeof(*packet));
93   bytes = safe_read(fd, packet, sizeof(*packet));   bytes = safe_read(fd, packet, sizeof(*packet));
94   if (bytes < 0) {   if (bytes < 0) {
95   DEBUG("cannot read on listening socket, ignoring");   log1("Packet read error, ignoring");
96   return bytes; /* returns -1 */   return bytes; /* returns -1 */
97   }   }
98    
99   if (packet->cookie != htonl(DHCP_MAGIC)) {   if (packet->cookie != htonl(DHCP_MAGIC)) {
100   bb_error_msg("received bogus message, ignoring");   bb_info_msg("Packet with bad magic, ignoring");
101   return -2;   return -2;
102   }   }
103   DEBUG("Received a packet");   log1("Received a packet");
104     udhcp_dump_packet(packet);
105    
106   if (packet->op == BOOTREQUEST) {   if (packet->op == BOOTREQUEST) {
107   vendor = get_option(packet, DHCP_VENDOR);   vendor = get_option(packet, DHCP_VENDOR);
# Line 65  int FAST_FUNC udhcp_recv_kernel_packet(s Line 116  int FAST_FUNC udhcp_recv_kernel_packet(s
116   if (vendor[OPT_LEN - 2] == (uint8_t)strlen(broken_vendors[i])   if (vendor[OPT_LEN - 2] == (uint8_t)strlen(broken_vendors[i])
117   && !strncmp((char*)vendor, broken_vendors[i], vendor[OPT_LEN - 2])   && !strncmp((char*)vendor, broken_vendors[i], vendor[OPT_LEN - 2])
118   ) {   ) {
119   DEBUG("broken client (%s), forcing broadcast replies",   log1("Broken client (%s), forcing broadcast replies",
120   broken_vendors[i]);   broken_vendors[i]);
121   packet->flags |= htons(BROADCAST_FLAG);   packet->flags |= htons(BROADCAST_FLAG);
122   }   }
# Line 74  int FAST_FUNC udhcp_recv_kernel_packet(s Line 125  int FAST_FUNC udhcp_recv_kernel_packet(s
125   if (vendor[OPT_LEN - 2] == (uint8_t)(sizeof("MSFT 98")-1)   if (vendor[OPT_LEN - 2] == (uint8_t)(sizeof("MSFT 98")-1)
126   && memcmp(vendor, "MSFT 98", sizeof("MSFT 98")-1) == 0   && memcmp(vendor, "MSFT 98", sizeof("MSFT 98")-1) == 0
127   ) {   ) {
128   DEBUG("broken client (%s), forcing broadcast replies", "MSFT 98");   log1("Broken client (%s), forcing broadcast replies", "MSFT 98");
129   packet->flags |= htons(BROADCAST_FLAG);   packet->flags |= htons(BROADCAST_FLAG);
130   }   }
131  #endif  #endif
# Line 84  int FAST_FUNC udhcp_recv_kernel_packet(s Line 135  int FAST_FUNC udhcp_recv_kernel_packet(s
135   return bytes;   return bytes;
136  }  }
137    
   
138  uint16_t FAST_FUNC udhcp_checksum(void *addr, int count)  uint16_t FAST_FUNC udhcp_checksum(void *addr, int count)
139  {  {
140   /* Compute Internet Checksum for "count" bytes   /* Compute Internet Checksum for "count" bytes
141   *         beginning at location "addr".   * beginning at location "addr".
142   */   */
143   int32_t sum = 0;   int32_t sum = 0;
144   uint16_t *source = (uint16_t *) addr;   uint16_t *source = (uint16_t *) addr;
# Line 114  uint16_t FAST_FUNC udhcp_checksum(void * Line 164  uint16_t FAST_FUNC udhcp_checksum(void *
164   return ~sum;   return ~sum;
165  }  }
166    
   
167  /* Construct a ip/udp header for a packet, send packet */  /* Construct a ip/udp header for a packet, send packet */
168  int FAST_FUNC udhcp_send_raw_packet(struct dhcpMessage *payload,  int FAST_FUNC udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt,
169   uint32_t source_ip, int source_port,   uint32_t source_ip, int source_port,
170   uint32_t dest_ip, int dest_port, const uint8_t *dest_arp,   uint32_t dest_ip, int dest_port, const uint8_t *dest_arp,
171   int ifindex)   int ifindex)
172  {  {
173   struct sockaddr_ll dest;   struct sockaddr_ll dest;
174   struct udp_dhcp_packet packet;   struct ip_udp_dhcp_packet packet;
175   int fd;   int fd;
176   int result = -1;   int result = -1;
177   const char *msg;   const char *msg;
178    
179   enum {   enum {
180   IP_UPD_DHCP_SIZE = sizeof(struct udp_dhcp_packet) - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS,   IP_UPD_DHCP_SIZE = sizeof(struct ip_udp_dhcp_packet) - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS,
181   UPD_DHCP_SIZE    = IP_UPD_DHCP_SIZE - offsetof(struct udp_dhcp_packet, udp),   UPD_DHCP_SIZE    = IP_UPD_DHCP_SIZE - offsetof(struct ip_udp_dhcp_packet, udp),
182   };   };
183    
184   fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));   fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
# Line 140  int FAST_FUNC udhcp_send_raw_packet(stru Line 189  int FAST_FUNC udhcp_send_raw_packet(stru
189    
190   memset(&dest, 0, sizeof(dest));   memset(&dest, 0, sizeof(dest));
191   memset(&packet, 0, sizeof(packet));   memset(&packet, 0, sizeof(packet));
192   packet.data = *payload; /* struct copy */   packet.data = *dhcp_pkt; /* struct copy */
193    
194   dest.sll_family = AF_PACKET;   dest.sll_family = AF_PACKET;
195   dest.sll_protocol = htons(ETH_P_IP);   dest.sll_protocol = htons(ETH_P_IP);
# Line 173  int FAST_FUNC udhcp_send_raw_packet(stru Line 222  int FAST_FUNC udhcp_send_raw_packet(stru
222   * If you need to change this: last byte of the packet is   * If you need to change this: last byte of the packet is
223   * packet.data.options[end_option(packet.data.options)]   * packet.data.options[end_option(packet.data.options)]
224   */   */
225     udhcp_dump_packet(dhcp_pkt);
226   result = sendto(fd, &packet, IP_UPD_DHCP_SIZE, 0,   result = sendto(fd, &packet, IP_UPD_DHCP_SIZE, 0,
227   (struct sockaddr *) &dest, sizeof(dest));   (struct sockaddr *) &dest, sizeof(dest));
228   msg = "sendto";   msg = "sendto";
# Line 185  int FAST_FUNC udhcp_send_raw_packet(stru Line 235  int FAST_FUNC udhcp_send_raw_packet(stru
235   return result;   return result;
236  }  }
237    
   
238  /* Let the kernel do all the work for packet generation */  /* Let the kernel do all the work for packet generation */
239  int FAST_FUNC udhcp_send_kernel_packet(struct dhcpMessage *payload,  int FAST_FUNC udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt,
240   uint32_t source_ip, int source_port,   uint32_t source_ip, int source_port,
241   uint32_t dest_ip, int dest_port)   uint32_t dest_ip, int dest_port)
242  {  {
# Line 197  int FAST_FUNC udhcp_send_kernel_packet(s Line 246  int FAST_FUNC udhcp_send_kernel_packet(s
246   const char *msg;   const char *msg;
247    
248   enum {   enum {
249   DHCP_SIZE = sizeof(struct dhcpMessage) - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS,   DHCP_SIZE = sizeof(struct dhcp_packet) - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS,
250   };   };
251    
252   fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);   fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
# Line 226  int FAST_FUNC udhcp_send_kernel_packet(s Line 275  int FAST_FUNC udhcp_send_kernel_packet(s
275   }   }
276    
277   /* Currently we send full-sized DHCP packets (see above) */   /* Currently we send full-sized DHCP packets (see above) */
278   result = safe_write(fd, payload, DHCP_SIZE);   udhcp_dump_packet(dhcp_pkt);
279     result = safe_write(fd, dhcp_pkt, DHCP_SIZE);
280   msg = "write";   msg = "write";
281   ret_close:   ret_close:
282   close(fd);   close(fd);

Legend:
Removed from v.983  
changed lines
  Added in v.984