⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 icmp.c

📁 An implementation of the TCP/IP protocol suite for the LINUX operating system. INET is implemented u
💻 C
📖 第 1 页 / 共 2 页
字号:
224                 printk("ICMP: cannot handle TOS redirects yet!\n");
225                 break;
226         default:
227                 DPRINTF((DBG_ICMP, "ICMP: Unreach: CODE=%d\n",
228                                                 (icmph->code & 7)));
229                 break;
230   }
231   skb->sk = NULL;
232   kfree_skb(skb, FREE_READ);
233 }
234 
235 
236 /* Handle ICMP_ECHO ("ping") requests. */
237 static void
238 icmp_echo(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev,
239           unsigned long saddr, unsigned long daddr, int len,
240           struct options *opt)
241 {
242   struct icmphdr *icmphr;
243   struct sk_buff *skb2;
244   int size, offset;
245 
246   size = sizeof(struct sk_buff) + dev->hard_header_len + 64 + len;
247   skb2 = alloc_skb(size, GFP_ATOMIC);
248   if (skb2 == NULL) {
249         skb->sk = NULL;
250         kfree_skb(skb, FREE_READ);
251         return;
252   }
253   skb2->sk = NULL;
254   skb2->mem_addr = skb2;
255   skb2->mem_len = size;
256   skb2->free = 1;
257 
258   /* Build Layer 2-3 headers for message back to source */
259   offset = ip_build_header(skb2, daddr, saddr, &dev,
260                                 IPPROTO_ICMP, opt, len, skb->ip_hdr->tos,255);
261   if (offset < 0) {
262         printk("ICMP: Could not build IP Header for ICMP ECHO Response\n");
263         kfree_skb(skb2,FREE_WRITE);
264         skb->sk = NULL;
265         kfree_skb(skb, FREE_READ);
266         return;
267   }
268 
269   /* Re-adjust length according to actual IP header size. */
270   skb2->len = offset + len;
271 
272   /* Build ICMP_ECHO Response message. */
273   icmphr = (struct icmphdr *) (skb2->data + offset);
274   memcpy((char *) icmphr, (char *) icmph, len);
275   icmphr->type = ICMP_ECHOREPLY;
276   icmphr->code = 0;
277   icmphr->checksum = 0;
278   icmphr->checksum = ip_compute_csum((unsigned char *)icmphr, len);
279 
280   /* Ship it out - free it when done */
281   ip_queue_xmit((struct sock *)NULL, dev, skb2, 1);
282 
283   skb->sk = NULL;
284   kfree_skb(skb, FREE_READ);
285 }
286 
287 
288 /* Handle the ICMP INFORMATION REQUEST. */
289 static void
290 icmp_info(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev,
291           unsigned long saddr, unsigned long daddr, int len,
292           struct options *opt)
293 {
294   /* NOT YET */
295   skb->sk = NULL;
296   kfree_skb(skb, FREE_READ);
297 }
298 
299 
300 /* Handle ICMP_ADRESS_MASK requests. */
301 static void
302 icmp_address(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev,
303           unsigned long saddr, unsigned long daddr, int len,
304           struct options *opt)
305 {
306   struct icmphdr *icmphr;
307   struct sk_buff *skb2;
308   int size, offset;
309 
310   size = sizeof(struct sk_buff) + dev->hard_header_len + 64 + len;
311   skb2 = alloc_skb(size, GFP_ATOMIC);
312   if (skb2 == NULL) {
313         skb->sk = NULL;
314         kfree_skb(skb, FREE_READ);
315         return;
316   }
317   skb2->sk = NULL;
318   skb2->mem_addr = skb2;
319   skb2->mem_len = size;
320   skb2->free = 1;
321 
322   /* Build Layer 2-3 headers for message back to source */
323   offset = ip_build_header(skb2, daddr, saddr, &dev,
324                                 IPPROTO_ICMP, opt, len, skb->ip_hdr->tos,255);
325   if (offset < 0) {
326         printk("ICMP: Could not build IP Header for ICMP ADDRESS Response\n");
327         kfree_skb(skb2,FREE_WRITE);
328         skb->sk = NULL;
329         kfree_skb(skb, FREE_READ);
330         return;
331   }
332 
333   /* Re-adjust length according to actual IP header size. */
334   skb2->len = offset + len;
335 
336   /* Build ICMP ADDRESS MASK Response message. */
337   icmphr = (struct icmphdr *) (skb2->data + offset);
338   icmphr->type = ICMP_ADDRESSREPLY;
339   icmphr->code = 0;
340   icmphr->checksum = 0;
341   icmphr->un.echo.id = icmph->un.echo.id;
342   icmphr->un.echo.sequence = icmph->un.echo.sequence;
343   memcpy((char *) (icmphr + 1), (char *) &dev->pa_mask, sizeof(dev->pa_mask));
344 
345   icmphr->checksum = ip_compute_csum((unsigned char *)icmphr, len);
346 
347   /* Ship it out - free it when done */
348   ip_queue_xmit((struct sock *)NULL, dev, skb2, 1);
349 
350   skb->sk = NULL;
351   kfree_skb(skb, FREE_READ);
352 }
353 
354 
355 /* Deal with incoming ICMP packets. */
356 int
357 icmp_rcv(struct sk_buff *skb1, struct device *dev, struct options *opt,
358          unsigned long daddr, unsigned short len,
359          unsigned long saddr, int redo, struct inet_protocol *protocol)
360 {
361   struct icmphdr *icmph;
362   unsigned char *buff;
363 
364   /* Drop broadcast packets. */
365   if (chk_addr(daddr) == IS_BROADCAST) {
366         DPRINTF((DBG_ICMP, "ICMP: Discarded broadcast from %s\n",
367                                                         in_ntoa(saddr)));
368         skb1->sk = NULL;
369         kfree_skb(skb1, FREE_READ);
370         return(0);
371   }
372 
373   buff = skb1->h.raw;
374   icmph = (struct icmphdr *) buff;
375 
376   /* Validate the packet first */
377   if (ip_compute_csum((unsigned char *) icmph, len)) {
378         /* Failed checksum! */
379         printk("ICMP: failed checksum from %s!\n", in_ntoa(saddr));
380         skb1->sk = NULL;
381         kfree_skb(skb1, FREE_READ);
382         return(0);
383   }
384   print_icmp(icmph);
385 
386   /* Parse the ICMP message */
387   switch(icmph->type) {
388         case ICMP_TIME_EXCEEDED:
389         case ICMP_DEST_UNREACH:
390         case ICMP_SOURCE_QUENCH:
391                 icmp_unreach(icmph, skb1);
392                 return(0);
393         case ICMP_REDIRECT:
394                 icmp_redirect(icmph, skb1, dev);
395                 return(0);
396         case ICMP_ECHO: 
397                 icmp_echo(icmph, skb1, dev, saddr, daddr, len, opt);
398                 return 0;
399         case ICMP_ECHOREPLY:
400                 skb1->sk = NULL;
401                 kfree_skb(skb1, FREE_READ);
402                 return(0);
403         case ICMP_INFO_REQUEST:
404                 icmp_info(icmph, skb1, dev, saddr, daddr, len, opt);
405                 return 0;
406         case ICMP_INFO_REPLY:
407                 skb1->sk = NULL;
408                 kfree_skb(skb1, FREE_READ);
409                 return(0);
410         case ICMP_ADDRESS:
411                 icmp_address(icmph, skb1, dev, saddr, daddr, len, opt);
412                 return 0;
413         case ICMP_ADDRESSREPLY:
414                 skb1->sk = NULL;
415                 kfree_skb(skb1, FREE_READ);
416                 return(0);
417         default:
418                 DPRINTF((DBG_ICMP,
419                         "ICMP: Unsupported ICMP from %s, type = 0x%X\n",
420                                                 in_ntoa(saddr), icmph->type));
421                 skb1->sk = NULL;
422                 kfree_skb(skb1, FREE_READ);
423                 return(0);
424   }
425   /*NOTREACHED*/
426   skb1->sk = NULL;
427   kfree_skb(skb1, FREE_READ);
428   return(-1);
429 }
430 
431 
432 /* Perform any ICMP-related I/O control requests. */
433 int
434 icmp_ioctl(struct sock *sk, int cmd, unsigned long arg)
435 {
436   switch(cmd) {
437         case DDIOCSDBG:
438                 return(dbg_ioctl((void *) arg, DBG_ICMP));
439         default:
440                 return(-EINVAL);
441   }
442   return(0);
443 }
444 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -