Changeset 30399 in vbox for trunk/src/VBox/Devices/Network/slirp/ip_icmp.c
- Timestamp:
- Jun 23, 2010 3:52:15 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 63019
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/slirp/ip_icmp.c
r30366 r30399 330 330 { 331 331 register struct icmp *icp; 332 int fIcpOnMbuf = 1; /* if icp pointer to m->m_data */ 332 333 register struct ip *ip = mtod(m, struct ip *); 333 334 int icmplen = ip->ip_len; … … 354 355 /* min 8 bytes payload */ 355 356 icmpstat.icps_tooshort++; 356 freeit:357 m_freem(pData, m);358 357 goto end_error; 359 358 } … … 361 360 m->m_len -= hlen; 362 361 m->m_data += hlen; 362 363 if (cksum(m, icmplen)) 364 { 365 icmpstat.icps_checksum++; 366 goto end_error; 367 } 368 363 369 if (m->m_next != NULL) 364 370 { 365 371 char *buf = RTMemAlloc(icmplen); 372 if (!buf) 373 { 374 LogRel(("NAT: not enought memory to allocate the buffer\n")); 375 goto end_error; 376 } 366 377 m_copydata(m, 0, icmplen, buf); 367 378 icp = (struct icmp *)buf; 379 fIcpOnMbuf = 0; 368 380 } 369 381 else 370 {371 382 icp = mtod(m, struct icmp *); 372 } 373 if (cksum(m, icmplen)) 374 { 375 icmpstat.icps_checksum++; 376 goto freeit; 377 } 383 384 378 385 m->m_len += hlen; 379 386 m->m_data -= hlen; … … 394 401 ip->ip_src.s_addr = dst; 395 402 icmp_reflect(pData, m); 403 if (!fIcpOnMbuf) 404 RTMemFree(icp); 405 return; 396 406 } 397 407 else … … 421 431 { 422 432 ssize_t rc; 423 m->m_so = &pData->icmp_socket;424 icmp_attach(pData, m);425 433 ttl = ip->ip_ttl; 426 434 Log(("NAT/ICMP: try to set TTL(%d)\n", ttl)); … … 432 440 rc = sendto(pData->icmp_socket.s, icp, icmplen, 0, 433 441 (struct sockaddr *)&addr, sizeof(addr)); 434 if (rc <0)442 if (rc >= 0) 435 443 { 436 LogRel((dfd,"icmp_input udp sendto tx errno = %d-%s\n", 437 errno, strerror(errno))); 438 icmp_error(pData, m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, strerror(errno)); 444 icmp_attach(pData, m); 445 m->m_so = &pData->icmp_socket; 446 /* don't let m_freem at the end free atached buffer */ 447 return; 439 448 } 440 } 441 else 442 { 443 /* 444 * We're freeing the ICMP message, which unable sent or process. 445 * That behavior described in rfc 793, we shouldn't notify sender about 446 * fail of processing it's ICMP packets 447 */ 448 m_freem(pData, m); 449 return; 449 450 LogRel((dfd,"icmp_input udp sendto tx errno = %d-%s\n", 451 errno, strerror(errno))); 452 icmp_error(pData, m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, strerror(errno)); 450 453 } 451 454 #else /* RT_OS_WINDOWS */ 452 icmp_attach(pData, m);453 455 pData->icmp_socket.so_laddr.s_addr = ip->ip_src.s_addr; /* XXX: hack*/ 454 456 pData->icmp_socket.so_icmp_id = icp->icmp_id; 455 457 pData->icmp_socket.so_icmp_seq = icp->icmp_seq; 456 m->m_so = &pData->icmp_socket;457 458 memset(&ipopt, 0, sizeof(IP_OPTION_INFORMATION)); 458 459 ipopt.Ttl = ip->ip_ttl; 459 460 status = ICMP_SEND_ECHO(pData->phEvents[VBOX_ICMP_EVENT_INDEX], notify_slirp, addr.sin_addr.s_addr, 460 461 icp->icmp_data, icmplen - ICMP_MINLEN, &ipopt); 461 if (status == 0 && (error = GetLastError()) != ERROR_IO_PENDING) 462 error = GetLastError(); 463 if ( status != 0 464 || error == ERROR_IO_PENDING) 462 465 { 463 error = GetLastError(); 464 LogRel(("NAT: Error (%d) occurred while sending ICMP (", error)); 465 switch (error) 466 { 467 case ERROR_INVALID_PARAMETER: 468 LogRel(("icmp_socket:%lx is invalid)\n", pData->icmp_socket.s)); 469 break; 470 case ERROR_NOT_SUPPORTED: 471 LogRel(("operation is unsupported)\n")); 472 break; 473 case ERROR_NOT_ENOUGH_MEMORY: 474 LogRel(("OOM!!!)\n")); 475 break; 476 case IP_BUF_TOO_SMALL: 477 LogRel(("Buffer too small)\n")); 478 break; 479 default: 480 LogRel(("Other error!!!)\n")); 481 break; 482 } 466 icmp_attach(pData, m); 467 m->m_so = &pData->icmp_socket; 468 /* don't let m_freem at the end free atached buffer */ 469 return; 470 } 471 LogRel(("NAT: Error (%d) occurred while sending ICMP (", error)); 472 switch (error) 473 { 474 case ERROR_INVALID_PARAMETER: 475 LogRel(("icmp_socket:%lx is invalid)\n", pData->icmp_socket.s)); 476 break; 477 case ERROR_NOT_SUPPORTED: 478 LogRel(("operation is unsupported)\n")); 479 break; 480 case ERROR_NOT_ENOUGH_MEMORY: 481 LogRel(("OOM!!!)\n")); 482 break; 483 case IP_BUF_TOO_SMALL: 484 LogRel(("Buffer too small)\n")); 485 break; 486 default: 487 LogRel(("Other error!!!)\n")); 488 break; 483 489 } 484 490 #endif /* RT_OS_WINDOWS */ … … 486 492 break; 487 493 case ICMP_UNREACH: 488 /* XXX? report error? close socket? */489 494 case ICMP_TIMXCEED: 495 /* @todo(vvl): both up cases comes from guest, 496 * indeed right solution would be find the socket 497 * corresponding to ICMP data and close it. 498 */ 490 499 case ICMP_PARAMPROB: 491 500 case ICMP_SOURCEQUENCH: … … 494 503 case ICMP_REDIRECT: 495 504 icmpstat.icps_notsupp++; 496 m_freem(pData, m);497 505 break; 498 506 499 507 default: 500 508 icmpstat.icps_badtype++; 501 m_freem(pData, m);502 509 } /* switch */ 503 if (m->m_next != NULL && icp != NULL) 510 511 end_error: 512 m_freem(pData, m); 513 if ( !fIcpOnMbuf 514 && !icp) 504 515 RTMemFree(icp); 505 506 end_error:507 /* m is m_free()'d xor put in a socket xor or given to ip_send */508 ;509 516 } 510 517 … … 684 691 /* 685 692 * Reflect the ip packet back to the source 693 * Note: m isn't duplicated by this method and more delivered to ip_output then. 686 694 */ 687 695 void
Note:
See TracChangeset
for help on using the changeset viewer.