커널에서 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 ;
}