עשיתי שרת udp שמקבל מערך של בתים שמייצג חבילות raw והוא צריך לשלוח את זה לרשת בצורה של raw.
עכשיו הבעיה שזה שולח חבילות dns אז אחרי זה הקרנל משנה את הפורט מקור מ53 ל1.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <linux/types.h>
#include <errno.h>
#include <limits.h>
#include <netinet/udp.h>
#include <netinet/ip.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <arpa/inet.h>
void printBufHex(unsigned char* buf,int len){
int i;
for(i = 0;i<len;i++){
printf("0x%02x ,",buf[i]);
if((i%16) == 16-1) printf("\n");
}
printf("\n");
}
int main(int argc, char**argv)
{
int sockfd,n;
int raw_socket;
struct sockaddr_in servaddr,cliaddr;
socklen_t len;
char mesg[10000];
sockfd =socket(AF_INET,SOCK_DGRAM,0);
raw_socket = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr=inet_addr("127.0.7.7");
servaddr.sin_port=htons(7777);
bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
//int flag = 0;
//int setsockoptr = setsockopt(raw_socket, IPPROTO_IP, IP_HDRINCL, &flag, sizeof(flag));
//printf(">>>>>> setsockoptr %d \n",setsockoptr);
for (;;)
{
len = sizeof(cliaddr);
n = recvfrom(sockfd,mesg,1000,0,(struct sockaddr *)&cliaddr,&len);
struct iphdr *out_ip_header = (struct iphdr *)&mesg;
struct sockaddr_in outaddr;
outaddr.sin_port = 0;
outaddr.sin_family = AF_INET;
memcpy(&outaddr.sin_addr, &out_ip_header->daddr, sizeof(struct in_addr));
int sendto_in = sendto(raw_socket , mesg, n ,
MSG_DONTWAIT, (struct sockaddr *)&outaddr, sizeof(struct sockaddr_in));
printf(">>>>>> sendto In %d \n",sendto_in);
printBufHex((unsigned char*)&mesg, n);
}
}
אם אני עושה את זה ככה בלי שרת אלא שולח מערך של בתים כאילו קיבלתי מהשרת. אז הקרנל משנה את הפורט יעד.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <linux/types.h>
#include <errno.h>
#include <limits.h>
#include <netinet/udp.h>
#include <netinet/ip.h>
#include <string.h>
char buf[] = {
0x45 ,0x00 ,0x00 ,0x62 ,0x00 ,0x00 ,0x40 ,0x00 ,0x3c ,0x11 ,0x1f ,0x72 ,0x08 ,0x08 ,0x08 ,0x08 ,
0x0a ,0x05 ,0x05 ,0x05 ,0x00 ,0x35 ,0xe8 ,0xd3 ,0x00 ,0x4e ,0x00 ,0x00 ,0x61 ,0xda ,0x81 ,0x80 ,
0x00 ,0x01 ,0x00 ,0x02 ,0x00 ,0x00 ,0x00 ,0x00 ,0x04 ,0x74 ,0x61 ,0x6c ,0x6b ,0x06 ,0x67 ,0x6f ,
0x6f ,0x67 ,0x6c ,0x65 ,0x03 ,0x63 ,0x6f ,0x6d ,0x00 ,0x00 ,0x01 ,0x00 ,0x01 ,0xc0 ,0x0c ,0x00 ,
0x05 ,0x00 ,0x01 ,0x00 ,0x00 ,0x54 ,0x4d ,0x00 ,0x09 ,0x04 ,0x74 ,0x61 ,0x6c ,0x6b ,0x01 ,0x6c ,
0xc0 ,0x11 ,0xc0 ,0x2d ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x00 ,0x01 ,0x19 ,0x00 ,0x04 ,0x4a ,0x7d ,
0x88 ,0x7d
};
int main(int argc, char **argv)
{
struct iphdr *_udp_ip_header ;
_udp_ip_header = (struct iphdr *)&buf;
int udp_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
printf("socket %d \n",udp_socket);
struct sockaddr_in sin;
sin.sin_port = 0;
sin.sin_family = AF_INET;
memcpy(&sin.sin_addr, &_udp_ip_header->daddr, sizeof(struct in_addr));
int i =0;
int sendto_i;
for(;i<7;i++){
sendto_i = sendto(udp_socket , buf, sizeof(buf),
MSG_DONTWAIT, (struct sockaddr *)&sin, sizeof(struct sockaddr_in));
printf("sendTo %d Bytes \n",sendto_i);
}
exit(0);
}
איך אפשר לשלוח חבילות בלי שהקרנל ישנה לי את התוכן שלהם.
פורסם במקור בפורום CODE613 ב14/02/2014 12:35 (+02:00)