24 |
|
|
25 |
#include "utils.h" |
#include "utils.h" |
26 |
#include "net.h" |
#include "net.h" |
27 |
|
#include "crc.h" |
28 |
|
|
29 |
/* |
/* |
30 |
* IP mask table, which allows to find quickly a network mask |
* IP mask table, which allows to find quickly a network mask |
354 |
|
|
355 |
#if HAS_RFC2553 |
#if HAS_RFC2553 |
356 |
/* Listen on the specified port */ |
/* Listen on the specified port */ |
357 |
int ip_listen(int port,int sock_type,int max_fd,int fd_array[]) |
int ip_listen(char *ip_addr,int port,int sock_type,int max_fd,int fd_array[]) |
358 |
{ |
{ |
359 |
struct addrinfo hints,*res,*res0; |
struct addrinfo hints,*res,*res0; |
360 |
char port_str[20]; |
char port_str[20],*addr; |
361 |
int nsock,error,i; |
int nsock,error,i; |
362 |
int reuse = 1; |
int reuse = 1; |
363 |
|
|
370 |
hints.ai_flags = AI_PASSIVE; |
hints.ai_flags = AI_PASSIVE; |
371 |
|
|
372 |
snprintf(port_str,sizeof(port_str),"%d",port); |
snprintf(port_str,sizeof(port_str),"%d",port); |
373 |
|
addr = (ip_addr && strlen(ip_addr)) ? ip_addr : NULL; |
374 |
|
|
375 |
if ((error = getaddrinfo(NULL,port_str,&hints,&res0)) != 0) { |
if ((error = getaddrinfo(addr,port_str,&hints,&res0)) != 0) { |
376 |
fprintf(stderr,"ip_listen: %s", gai_strerror(error)); |
fprintf(stderr,"ip_listen: %s", gai_strerror(error)); |
377 |
return(-1); |
return(-1); |
378 |
} |
} |
392 |
setsockopt(fd_array[nsock],SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)); |
setsockopt(fd_array[nsock],SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)); |
393 |
|
|
394 |
if ((bind(fd_array[nsock],res->ai_addr,res->ai_addrlen) < 0) || |
if ((bind(fd_array[nsock],res->ai_addr,res->ai_addrlen) < 0) || |
395 |
(listen(fd_array[nsock],5) < 0)) |
((sock_type == SOCK_STREAM) && (listen(fd_array[nsock],5) < 0))) |
396 |
{ |
{ |
397 |
close(fd_array[nsock]); |
close(fd_array[nsock]); |
398 |
fd_array[nsock] = -1; |
fd_array[nsock] = -1; |
407 |
} |
} |
408 |
#else |
#else |
409 |
/* Listen on the specified port */ |
/* Listen on the specified port */ |
410 |
int ip_listen(int port,int sock_type,int max_fd,int fd_array[]) |
int ip_listen(char *ip_addr,int port,int sock_type,int max_fd,int fd_array[]) |
411 |
{ |
{ |
412 |
struct sockaddr_in sin; |
struct sockaddr_in sin; |
413 |
int i,sck,reuse=1; |
int i,sck,reuse=1; |
425 |
sin.sin_family = PF_INET; |
sin.sin_family = PF_INET; |
426 |
sin.sin_port = htons(port); |
sin.sin_port = htons(port); |
427 |
|
|
428 |
|
if (ip_addr && strlen(ip_addr)) |
429 |
|
sin.sin_addr.s_addr = inet_addr(ip_addr); |
430 |
|
|
431 |
setsockopt(fd_array[0],SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)); |
setsockopt(fd_array[0],SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)); |
432 |
|
|
433 |
if (bind(sck,(struct sockaddr *)&sin,sizeof(sin)) < 0) { |
if (bind(sck,(struct sockaddr *)&sin,sizeof(sin)) < 0) { |
435 |
goto error; |
goto error; |
436 |
} |
} |
437 |
|
|
438 |
if (listen(sck,5) < 0) { |
if ((sock_type == SOCK_STREAM) && (listen(sck,5) < 0)) { |
439 |
perror("ip_listen: listen"); |
perror("ip_listen: listen"); |
440 |
goto error; |
goto error; |
441 |
} |
} |
448 |
return(-1); |
return(-1); |
449 |
} |
} |
450 |
#endif |
#endif |
451 |
|
|
452 |
|
/* |
453 |
|
* ISL rewrite. |
454 |
|
* |
455 |
|
* See: http://www.cisco.com/en/US/tech/tk389/tk390/technologies_tech_note09186a0080094665.shtml |
456 |
|
*/ |
457 |
|
void cisco_isl_rewrite(m_uint8_t *pkt,m_uint32_t tot_len) |
458 |
|
{ |
459 |
|
static m_uint8_t isl_xaddr[N_ETH_ALEN] = { 0x01,0x00,0x0c,0x00,0x10,0x00 }; |
460 |
|
u_int real_offset,real_len; |
461 |
|
n_eth_hdr_t *hdr; |
462 |
|
m_uint32_t ifcs; |
463 |
|
|
464 |
|
hdr = (n_eth_hdr_t *)pkt; |
465 |
|
if (!memcmp(&hdr->daddr,isl_xaddr,N_ETH_ALEN)) { |
466 |
|
real_offset = N_ETH_HLEN + N_ISL_HDR_SIZE; |
467 |
|
real_len = ntohs(hdr->type); |
468 |
|
real_len -= (N_ISL_HDR_SIZE + 4); |
469 |
|
|
470 |
|
if ((real_offset+real_len) > tot_len) |
471 |
|
return; |
472 |
|
|
473 |
|
/* Rewrite the destination MAC address */ |
474 |
|
hdr->daddr.eth_addr_byte[4] = 0x00; |
475 |
|
|
476 |
|
/* Compute the internal FCS on the encapsulated packet */ |
477 |
|
ifcs = crc32_compute(0xFFFFFFFF,pkt+real_offset,real_len); |
478 |
|
pkt[tot_len-4] = ifcs & 0xff; |
479 |
|
pkt[tot_len-3] = (ifcs >> 8) & 0xff; |
480 |
|
pkt[tot_len-2] = (ifcs >> 16) & 0xff; |
481 |
|
pkt[tot_len-1] = ifcs >> 24; |
482 |
|
} |
483 |
|
} |