Note2012. 3. 29. 15:24



커널에서 TCP 패킷 필요가 생겨 아래와 같이 코딩하여 전송하였음.

HTTP/XML 패킷 소스

/*

endbuffer sends "Length" bytes from "Buffer" through the socket "sock".

*/


size_t SendBuffer(struct socket *sock, const char *Buffer, size_t Length)

{

struct msghdr msg;

mm_segment_t oldfs; // mm_segment_t is just a long

struct iovec iov; // structure containing a base addr. and length

int len2;


//printk("Entering SendBuffer\n");



msg.msg_name = 0;

msg.msg_namelen = 0;

msg.msg_iov = &iov;

msg.msg_iovlen = 1; //point to be noted

msg.msg_control = NULL;

msg.msg_controllen = 0;


msg.msg_flags = MSG_NOSIGNAL;//0/*MSG_DONTWAIT*/;


iov.iov_base = (char*) Buffer; // as we know that iovec is 

iov.iov_len = (__kernel_size_t) Length; // nothing but a base addr and length




// #define get_fs() (current_thread_info()->addr_limit)

// similar for set_fs;

/*

  Therefore this line sets the "fs" to KERNEL_DS and saves its old value

  */

oldfs = get_fs(); set_fs(KERNEL_DS);


/* Actual Sending of the Message */

len2 = sock_sendmsg(sock,&msg,(size_t)(Length));


/* retrieve the old value of fs (whatever it is)*/

set_fs(oldfs);



return len2;

}



/* 

   Recieves data from the socket "sock" and puts it in the 'Buffer'.

   Returns the length of data recieved


   The Calling function must do a:

   Buffer = (char*) get_free_page(GFP_KERNEL);

   or a kmalloc to allocate kernel's memory

   (or it can use the kernel's stack space [very small] )


   */


size_t RecvBuffer(struct socket *sock, const char *Buffer, size_t Length) 

{

struct msghdr msg;

struct iovec iov;


int len;

mm_segment_t oldfs;


/* Set the msghdr structure*/

msg.msg_name = 0;

msg.msg_namelen = 0;

msg.msg_iov = &iov;

msg.msg_iovlen = 1;

msg.msg_control = NULL;

msg.msg_controllen = 0;

msg.msg_flags = 0;


/* Set the iovec structure*/

iov.iov_base = (void *) &Buffer[0];

iov.iov_len = (size_t)Length;


/* Recieve the message */

oldfs = get_fs(); set_fs(KERNEL_DS);

len = sock_recvmsg(sock,&msg,Length,0/*MSG_DONTWAIT*/); // let it wait if there is no message

set_fs(oldfs);


// if ((len!=-EAGAIN)&&(len!=0))

// printk("RecvBuffer Recieved %i bytes \n",len);


return len;

}


#define str_to_ip(a,b,c,d) (a << 24 | b<< 16 | c << 8 | d ) 

struct socket * set_up_client_socket(unsigned int IP_addr, int port_no) 

{

struct socket *clientsock = NULL;

struct sockaddr_in sin;

int error, i;


/* First create a socket */

error = sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&clientsock);

if (error<0) { 

printk("Error during creation of socket; terminating\n");

return 0;


/* Now bind and connect the socket */

memset(&sin, 0, sizeof(sin));

sin.sin_family = AF_INET;

//sin.sin_addr.s_addr = htonl(IP_addr);

/* TODO : 220.103.255.203 */

sin.sin_addr.s_addr = htonl((220 << 24 | 103 << 16 | 255 << 8 | 203));

//sin.sin_port = htons(port_no);

sin.sin_port = htons(8080);


error = security_socket_connect(clientsock, (struct sockaddr*)&sin,sizeof(sin));

for(i=0;i<10;i++) {

error = clientsock->ops->connect(clientsock,(struct sockaddr*)&sin,sizeof(sin),O_RDWR);

if (error<0) {

printk("Error connecting client socket to server: %i, retrying .. %d \n",error, i);

if(i==9) {

printk("Giving Up!\n"); return 0;

}

}

else break; //connected

}


return clientsock;


}


int send_reply(struct socket *sock, char *str)

{

struct msghdr msg;

struct iovec iov;

int len, written = 0, left = strlen(str);

mm_segment_t oldmm;


msg.msg_name     = 0;

msg.msg_namelen  = 0;

msg.msg_iov      = &iov;

msg.msg_iovlen   = 1;

msg.msg_control  = NULL;

msg.msg_controllen = 0;

msg.msg_flags    = MSG_DONTWAIT;


oldmm = get_fs(); set_fs(KERNEL_DS);


//repeat_send:

msg.msg_iov->iov_len = left;

msg.msg_iov->iov_base = (char *) str+ written;


len = sock_sendmsg(sock, &msg, left);


return written ? written : len;

}


static void send_dying_packet(void *data)

{

//struct sockaddr_in saddr, daddr;

struct socket *control= NULL;

char send_data[]="POST /TMS/acs HTTP/1.1\r\nHost: 1.2.3.4\r\nUser-Agent: gSOAP/2.7\r\nContent-Type: text/xml; charset=utf-8\r\nContent-Length: 1809\r\nConnection: keep-alive\r\nAuthorization: Basic \r\nSOAPAction: \r\n\r\n";

char xml_data[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:cwmp=\"urn:dslforum-org:cwmp-1-0\"><SOAP-ENV:Header><cwmp:ID SOAP-ENV:mustUnderstand=\"1\">2</cwmp:ID>"

char send_buff[2500];


set_user_nice(current, -20); 


//send_buff = kmalloc((sizeof(send_data) + sizeof(xml_data)), GFP_KERNEL);


sprintf(send_buff, "%s%s", send_data, xml_data);


control = set_up_client_socket(0,0);

//send_reply(control, send_data);

send_reply(control, send_buff);


return ;

}



Posted by 스카이데이즈