Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 583 → Rev 584

/shark/trunk/drivers/newnet/udpip.c
20,11 → 20,11
 
/**
------------
CVS : $Id: udpip.c,v 1.1 2004-04-23 14:30:35 mauro Exp $
CVS : $Id: udpip.c,v 1.2 2004-04-23 18:13:53 mauro Exp $
 
File: $File$
Revision: $Revision: 1.1 $
Last update: $Date: 2004-04-23 14:30:35 $
Revision: $Revision: 1.2 $
Last update: $Date: 2004-04-23 18:13:53 $
------------
**/
 
67,6 → 67,11
#include <drivers/udpip.h>
#include "arp.h"
 
//#define __UDP_DBG__
//#define __IP_DBG__
#define UDP_INFO "[UDP] "
#define IP_INFO "[IP] "
 
/*
UDP-buffers number and dimension (UDP-buffers are provided by NetBuff
module
99,461 → 104,465
/* TRUE if the IP addresses ip1 and ip2 are equal, FALSE otherwise */
int ip_compAddr(IP_ADDR ip1, IP_ADDR ip2)
{
int i;
int i;
for (i=0; i < 4; i++)
if (ip1.ad[i] != ip2.ad[i]) return FALSE;
return TRUE;
for (i=0; i < 4; i++)
if (ip1.ad[i] != ip2.ad[i]) return FALSE;
 
return TRUE;
}
 
/* traslate an IP address from text string to 4 bytes */
int ip_str2addr(char *a, IP_ADDR *ip)
{
int ad[6];
int i,j;
char c;
int ad[6];
int i,j;
char c;
 
i = 0;
for(j = 0; j < 4; j++) {
ad[j] = 0;
while((a[i] != '.') && (a[i] != 0)) {
c = a[i++];
if (c <= '9') c = c - '0';
else c = c - 'A' + 10;
ad[j] = ad[j] * 10 + c;
i = 0;
for(j = 0; j < 4; j++) {
ad[j] = 0;
while((a[i] != '.') && (a[i] != 0)) {
c = a[i++];
if (c <= '9') c = c - '0';
else c = c - 'A' + 10;
ad[j] = ad[j] * 10 + c;
}
i++;
}
i++;
}
 
for (i=0; i<4; i++) ip->ad[i] = ad[i];
return 1;
for (i=0; i<4; i++)
ip->ad[i] = ad[i];
 
return 1;
}
 
/* give the body of an IP packet */
void *ip_getFDB(void *pkt)
{
return((void *)(((BYTE *)eth_getFDB(pkt)) + sizeof(IP_HEADER)));
return((void *)(((BYTE *)eth_getFDB(pkt)) + sizeof(IP_HEADER)));
}
 
/* received IP packet CallBack */
void ip_server_recv(void *pkt)
{
IP_HEADER *iphd;
WORD *ptcheck;
WORD checksum,oldChk;
int hlen,i;
int done;
char dummystr[50];
BYTE flag;
IP_HEADER *iphd;
WORD *ptcheck;
WORD checksum,oldChk;
int hlen,i;
int done;
char dummystr[50];
BYTE flag;
 
UDP_HEADER *udphd;
struct pseudo_hd ph;
WORD sum, old;
WORD *p;
UDP_MSG usermsg;
void *b, *s;
UDP_HEADER *udphd;
struct pseudo_hd ph;
WORD sum, old;
WORD *p;
UDP_MSG usermsg;
void *b, *s;
 
/* debug...*/
netlev = 2;
/* debug...*/
netlev = 2;
 
sprintf(dummystr, "Packet arrived!\n");
iphd = (IP_HEADER *)eth_getFDB(pkt);
/* compute the checksum */
ptcheck = (WORD *)iphd;
sprintf(dummystr, "Packet arrived!\n");
iphd = (IP_HEADER *)eth_getFDB(pkt);
 
/* compute the checksum */
ptcheck = (WORD *)iphd;
#ifdef __IP_DBG__
ip_print_header(iphd);
//!!!ip_print_header(iphd);
#endif
hlen = getHlen(iphd->vers_hlen) * 2;
checksum = oldChk = *ptcheck;
ptcheck++;
for (i=1; i<hlen; i++) {
checksum += *ptcheck;
if (checksum < oldChk) checksum ++;
oldChk = checksum;
hlen = getHlen(iphd->vers_hlen) * 2;
checksum = oldChk = *ptcheck;
ptcheck++;
}
if (checksum != 0xffff) {
/* wrong ChkSum */
for (i=1; i<hlen; i++) {
checksum += *ptcheck;
if (checksum < oldChk) checksum ++;
oldChk = checksum;
ptcheck++;
}
if (checksum != 0xffff) {
/* wrong ChkSum */
#ifdef __IP_DBG__
sprintf(msg, "Wrong checksum! %x\n",checksum);
win_puts(&wip,msg);
printk(KERN_DEBUG IP_INFO "Wrong checksum: %x.\n", checksum);
#endif
} else if (!ip_compAddr(iphd->dest,myIpAddr)) {
} else if (!ip_compAddr(iphd->dest,myIpAddr)) {
#ifdef __IP_DBG__
win_puts(&wip,"Packet not addressed to this host!\n");
printk(KERN_DEBUG IP_INFO "Packet not addressed to this host.\n");
#endif
} else if (getFlags(ntohs(iphd->flags_frOffset)) & 0x01) {
} else if (getFlags(ntohs(iphd->flags_frOffset)) & 0x01) {
#ifdef __IP_DBG__
/* fragment? */
win_puts(&wip,"Gotta a fragment!\n");
/* fragment? */
printk(KERN_DEBUG IP_INFO "Gotta a fragment!\n");
#endif
} else if (getFrOffset(ntohs(iphd->flags_frOffset)) != 0) {
} else if (getFrOffset(ntohs(iphd->flags_frOffset)) != 0) {
#ifdef __IP_DBG__
win_puts(&wip,"Gotta a fragment again!\n");
printk(KERN_DEBUG IP_INFO "Gotta a fragment again!\n");
#endif
} else {
/* OK: the packet is good... */
if (iphd->protocol != IP_UDP_TYPE) {
/* It isn't an UDP packet */
done = FALSE;
i = 0;
while ((i < IP_MAX_ENTRIES) && !done) {
if (ipTable[i].protocol == iphd->protocol) done = TRUE;
else i++;
}
if (!done) {
} else {
/* OK: the packet is good... */
if (iphd->protocol != IP_UDP_TYPE) {
/* It isn't an UDP packet */
done = FALSE;
i = 0;
while ((i < IP_MAX_ENTRIES) && !done) {
if (ipTable[i].protocol == iphd->protocol) done = TRUE;
else i++;
}
if (!done) {
#ifdef __IP_DBG__
/* Unknown transport protocol */
win_puts(&wip,"Wrong protocol\n");
/* Unknown transport protocol */
printk(KERN_DEBUG IP_INFO "Wrong protocol.\n");
#endif
} else {
/* Call the correct transport protocol CallBack */
ipTable[i].rfun((void *)((BYTE *)iphd + 4*getHlen(iphd->vers_hlen)));
}
} else {
/* UDP packet */
netlev = 4;
udphd = (UDP_HEADER *)(void *)((BYTE *)iphd + 4*getHlen(iphd->vers_hlen));
/* compute the UDP checksum */
for (i = 0; i < 4; i++) {
ph.source.ad[i] = iphd->source.ad[i];
ph.dest.ad[i] = iphd->dest.ad[i];
}
ph.zero = 0;
ph.protocoll = IP_UDP_TYPE;
ph.len = udphd->mlen;
sum = 0;
old = 0;
p = (WORD *)&ph;
for (i = 0; i < (sizeof(ph) >> 1); i++) {
sum += p[i];
if (sum < old) sum ++;
old = sum;
}
} else {
/* Call the correct transport protocol CallBack */
ipTable[i].rfun((void *)((BYTE *)iphd + 4*getHlen(iphd->vers_hlen)));
}
} else {
/* UDP packet */
netlev = 4;
 
udphd = (UDP_HEADER *)(void *)((BYTE *)iphd + 4*getHlen(iphd->vers_hlen));
/* compute the UDP checksum */
for (i = 0; i < 4; i++) {
ph.source.ad[i] = iphd->source.ad[i];
ph.dest.ad[i] = iphd->dest.ad[i];
}
ph.zero = 0;
ph.protocoll = IP_UDP_TYPE;
ph.len = udphd->mlen;
sum = 0;
old = 0;
p = (WORD *)&ph;
for (i = 0; i < (sizeof(ph) >> 1); i++) {
sum += p[i];
if (sum < old) sum ++;
old = sum;
}
#ifdef __UDP_DBG__
sprintf(str,"half sum: %x\n",sum);
win_puts(&dbg,str);
printk(KERN_DEBUG UDP_INFO "Half sum: %x\n",sum);
#endif
p = (WORD *)udphd;
((BYTE *)udphd)[ntohs(udphd->mlen)] = 0;
for (i = 0; i < ((ntohs(udphd->mlen) + 1) >> 1); i++) {
sum += p[i];
if (sum < old) sum ++;
old = sum;
}
p = (WORD *)udphd;
((BYTE *)udphd)[ntohs(udphd->mlen)] = 0;
for (i = 0; i < ((ntohs(udphd->mlen) + 1) >> 1); i++) {
sum += p[i];
if (sum < old) sum ++;
old = sum;
}
#ifdef __UDP_DBG__
win_puts(&dbg,"UDP packet received!!!\n");
sprintf(str,"s_port: %x\n",udphd->s_port);
win_puts(&dbg,str);
sprintf(str,"d_port: %x\n",udphd->d_port);
win_puts(&dbg,str);
sprintf(str,"m_len: %x %d\n",udphd->mlen, ntohs(udphd->mlen));
win_puts(&dbg,str);
sprintf(str,"checksum: %x\n",udphd->checksum);
win_puts(&dbg,str);
sprintf(str,"mysum: %x \n", sum);
win_puts(&dbg,str);
printk(KERN_DEBUG UDP_INFO "Packet received.\n");
printk(KERN_DEBUG UDP_INFO "s_port: %x\n",udphd->s_port);
printk(KERN_DEBUG UDP_INFO "d_port: %x\n",udphd->d_port);
printk(KERN_DEBUG UDP_INFO "m_len: %x %d\n",udphd->mlen, ntohs(udphd->mlen));
printk(KERN_DEBUG UDP_INFO "checksum: %x\n",udphd->checksum);
printk(KERN_DEBUG UDP_INFO "mysum: %x \n", sum);
#endif
if(sum != 0xFFFF) {
/* Wrong UDP ChkSum */
cprintf("Error %x!!!!\n",sum);
kern_raise(XUDP_BADCHK_EXC,exec_shadow);
} else {
done = FALSE;
i = 0;
/* searching for the destination socket...*/
while((i < UDP_MAX_HANDLES) && !done) {
if ((udpTable[i].valid == TRUE) &&
(udpTable[i].port == ntohs(udphd->d_port)))
done = TRUE;
else i++;
}
if (done) {
/*...found! */
s = (void *)(((BYTE *)udphd) + sizeof(UDP_HEADER));
if (udpTable[i].notify == TRUE) {
/* notify function associated to the socket: call it */
udpTable[i].notify_fun(ntohs(udphd->mlen) - sizeof(UDP_HEADER),
s, udpTable[i].notify_par);
} else {
/* otherwise, send the packet to the correct port */
if((b = netbuff_get(&udp_rxbuff, NON_BLOCK)) != 0) {
memcpy(b,s,ntohs(udphd->mlen) - sizeof(UDP_HEADER) + 1);
setIpAddr(usermsg.addr.s_addr, iphd->source);
usermsg.addr.s_port = ntohs(udphd->s_port);
usermsg.mlen = ntohs(udphd->mlen) - sizeof(UDP_HEADER);
usermsg.buff = b;
flag = port_send(udpTable[i].hport,&usermsg,NON_BLOCK);
if (!flag) {
netbuff_release(&udp_rxbuff, b);
if(sum != 0xFFFF) {
/* Wrong UDP ChkSum */
cprintf("Error %x!\n", sum);
kern_raise(XUDP_BADCHK_EXC,exec_shadow);
} else {
done = FALSE;
i = 0;
/* searching for the destination socket...*/
while((i < UDP_MAX_HANDLES) && !done) {
if ((udpTable[i].valid == TRUE) && (udpTable[i].port == ntohs(udphd->d_port)))
done = TRUE;
else i++;
}
if (done) {
/*...found! */
s = (void *)(((BYTE *)udphd) + sizeof(UDP_HEADER));
if (udpTable[i].notify == TRUE) {
/* notify function associated to the socket: call it */
udpTable[i].notify_fun(ntohs(udphd->mlen) - sizeof(UDP_HEADER),
s, udpTable[i].notify_par);
} else {
/* otherwise, send the packet to the correct port */
if((b = netbuff_get(&udp_rxbuff, NON_BLOCK)) != 0) {
memcpy(b,s,ntohs(udphd->mlen) - sizeof(UDP_HEADER) + 1);
setIpAddr(usermsg.addr.s_addr, iphd->source);
usermsg.addr.s_port = ntohs(udphd->s_port);
usermsg.mlen = ntohs(udphd->mlen) - sizeof(UDP_HEADER);
usermsg.buff = b;
flag = port_send(udpTable[i].hport,&usermsg,NON_BLOCK);
if (!flag) {
netbuff_release(&udp_rxbuff, b);
#ifdef __UDP_DBG__
win_puts(&dbg,"Port is filled up ");
printk(KERN_DEBUG "Port is filled up.\n");
#endif
}
}
}
} else {
}
}
}
} else {
#ifdef __UDP_DBG__
win_puts(&dbg,"Port not found ");
printk(KERN_DEBUG UDP_INFO "Port not found.\n");
#endif
}
}
}
}
}
}
}
 
/* Send an IP packet */
void ip_send(IP_ADDR dest, void *pkt, WORD len)
{
static WORD ip_ident = 0;
IP_HEADER *iphd;
WORD check = 0, oldCheck = 0;
int i, done;
WORD *pt;
#ifdef __IP_DBG__
char msg[50];
#endif
iphd = (IP_HEADER *)eth_getFDB(pkt);
iphd->vers_hlen = (4 << 4) + 5;
iphd->servType = 8;
iphd->lenght = htons(len + sizeof(IP_HEADER));
iphd->ident = htons(ip_ident++);
iphd->flags_frOffset = 0;
iphd->ttl = 10;
iphd->protocol = IP_UDP_TYPE;
iphd->headChecksum = 0;
iphd->source = myIpAddr;
iphd->dest = dest;
static WORD ip_ident = 0;
IP_HEADER *iphd;
WORD check = 0, oldCheck = 0;
int i, done;
WORD *pt;
 
/* Compute the checksum */
pt = (WORD *)iphd;
check = oldCheck = *pt;
pt++;
for (i = 1; i < 10; i++) {
check += *pt;
if (oldCheck > check) check++;
oldCheck = check;
iphd = (IP_HEADER *)eth_getFDB(pkt);
iphd->vers_hlen = (4 << 4) + 5;
iphd->servType = 8;
iphd->lenght = htons(len + sizeof(IP_HEADER));
iphd->ident = htons(ip_ident++);
iphd->flags_frOffset = 0;
iphd->ttl = 10;
iphd->protocol = IP_UDP_TYPE;
iphd->headChecksum = 0;
iphd->source = myIpAddr;
iphd->dest = dest;
 
/* Compute the checksum */
pt = (WORD *)iphd;
check = oldCheck = *pt;
pt++;
}
check = ~check;
iphd->headChecksum = check;
for (i = 1; i < 10; i++) {
check += *pt;
if (oldCheck > check) check++;
oldCheck = check;
pt++;
}
check = ~check;
iphd->headChecksum = check;
#ifdef __IP_DBG__
sprintf(msg,"serv type : %d\n",iphd->servType);
win_puts(&wip,msg);
printk(KERN_DEBUG IP_INFO "Serv type : %d\n", iphd->servType);
#endif
/* Is the destination IP address the broadcast address?*/
if (ip_compAddr(dest,IPbroadcastaddress)) {
/* Send the packet*/
eth_setHeader(pkt,broadcast,ETH_IP_TYPE);
eth_sendPkt(pkt,len + sizeof(IP_HEADER));
netbuff_release(&udp_txbuff, (void *)pkt);
} else {
/* Is the destination ethernet address in the ARP table? */
i = 0; done = 0;
while (i < ARP_MAX_ENTRIES && !done)
if (arpTable[i].valid == TRUE) {
if (ip_compAddr(dest,arpTable[i].ip)) {
done = TRUE;
} else i++;
} else i++;
if (done == FALSE) {
/* No: call ARP to get the ethernet address */
arp_send(pkt,dest,len + sizeof(IP_HEADER));
} else {
/* Yes: directly send the packet */
eth_setHeader(pkt,arpTable[i].eth,ETH_IP_TYPE);
eth_sendPkt(pkt,len + sizeof(IP_HEADER));
netbuff_release(&udp_txbuff, (void *)pkt);
arpTable[i].used++;
if (arpTable[i].used > ARP_MAX_USED) arpTable[i].used = ARP_MAX_USED;
}
}
/* Is the destination IP address the broadcast address?*/
if (ip_compAddr(dest,IPbroadcastaddress)) {
/* Send the packet*/
eth_setHeader(pkt,broadcast,ETH_IP_TYPE);
eth_sendPkt(pkt,len + sizeof(IP_HEADER));
netbuff_release(&udp_txbuff, (void *)pkt);
} else {
/* Is the destination ethernet address in the ARP table? */
i = 0; done = 0;
while (i < ARP_MAX_ENTRIES && !done)
if (arpTable[i].valid == TRUE) {
if (ip_compAddr(dest,arpTable[i].ip)) {
done = TRUE;
} else i++;
} else i++;
if (done == FALSE) {
/* No: call ARP to get the ethernet address */
arp_send(pkt, dest, len + sizeof(IP_HEADER));
} else {
/* Yes: directly send the packet */
eth_setHeader(pkt,arpTable[i].eth,ETH_IP_TYPE);
eth_sendPkt(pkt, len + sizeof(IP_HEADER));
netbuff_release(&udp_txbuff, (void *)pkt);
arpTable[i].used++;
if (arpTable[i].used > ARP_MAX_USED) arpTable[i].used = ARP_MAX_USED;
}
}
}
 
/* let IP manage a new transport protocol */
int ip_setProtocol(BYTE proto, void (*recv)(void *m))
{
BYTE done, i;
BYTE done, i;
 
i = 0; done = 0;
while (i < IP_MAX_ENTRIES && !done)
if (ipTable[i].rfun == NULL) done = TRUE;
else i++;
if (!done) return FALSE;
else {
ipTable[i].protocol = proto;
ipTable[i].rfun = recv;
}
return TRUE;
i = 0; done = 0;
while (i < IP_MAX_ENTRIES && !done)
if (ipTable[i].rfun == NULL) done = TRUE;
else i++;
if (!done)
return FALSE;
else {
ipTable[i].protocol = proto;
ipTable[i].rfun = recv;
}
return TRUE;
}
 
//int ip_error(int code)
//{
// cprintf("IP error\n");
/* cprintf("Code [%d]\nCause : %s",code,ip_error_msg[code-IP_ERROR_BASE]);*/
// return(0);
//}
/*int ip_error(int code)
{
cprintf("IP error\n");
cprintf("Code [%d]\nCause : %s",code,ip_error_msg[code-IP_ERROR_BASE]);
return(0);
}*/
 
/* Initialize the IP layer: it also call the ARP initialization function, pass a struct ip_params* */
void ip_init(void *p)
{
int i;
int i;
 
if (!ipIsInstalled) {
arp_init(((struct ip_params*)p)->localAddr);
//exc_set(IP_INIT_ERROR,ip_error);
for (i=0; i < IP_MAX_ENTRIES; i++) ipTable[i].rfun = NULL;
if (!ipIsInstalled) {
arp_init(((struct ip_params*)p)->localAddr);
//exc_set(IP_INIT_ERROR,ip_error);
for (i=0; i < IP_MAX_ENTRIES; i++)
ipTable[i].rfun = NULL;
 
eth_setProtocol(ETH_IP_TYPE, ip_server_recv);
ip_str2addr(((struct ip_params*)p)->broadcastAddr,&IPbroadcastaddress);
ipIsInstalled = TRUE;
eth_str2Addr("FF:FF:FF:FF:FF:FF",&broadcast);
} else cprintf("IP: already installed!!!\n");
eth_setProtocol(ETH_IP_TYPE, ip_server_recv);
ip_str2addr(((struct ip_params*)p)->broadcastAddr,&IPbroadcastaddress);
ipIsInstalled = TRUE;
eth_str2Addr("FF:FF:FF:FF:FF:FF",&broadcast);
} else
cprintf("IP: already installed.\n");
}
 
/* Receive an UDP packet from a socket */
int udp_recvfrom(int s, void *buff, UDP_ADDR *from)
{
UDP_MSG u;
UDP_MSG u;
 
port_receive(udpTable[s].pport,&u,BLOCK);
memcpy(buff,u.buff,u.mlen);
netbuff_release(&udp_rxbuff, u.buff);
*from = u.addr;
return (u.mlen);
port_receive(udpTable[s].pport,&u,BLOCK);
memcpy(buff,u.buff,u.mlen);
netbuff_release(&udp_rxbuff, u.buff);
*from = u.addr;
 
return (u.mlen);
}
 
/* Associate a notify function to a socket */
int udp_notify(int s, int (*f)(int len, BYTE *buff, void *p), void *p)
{
if (f == NULL) {
udpTable[s].notify = FALSE;
if (f == NULL) {
udpTable[s].notify = FALSE;
return 1;
}
if (udpTable[s].valid != TRUE)
return -1;
udpTable[s].notify = TRUE;
udpTable[s].notify_fun = f;
udpTable[s].notify_par = p;
 
return 1;
}
 
if (udpTable[s].valid != TRUE) return -1;
udpTable[s].notify = TRUE;
udpTable[s].notify_fun = f;
udpTable[s].notify_par = p;
return 1;
}
 
/* Create a new socket binding it to a specified IP port */
int udp_bind(UDP_ADDR *local, IP_ADDR *bindlist)
{
int i, j;
BYTE done;
char str[30];
int i, j;
BYTE done;
char str[30];
 
/* Search for a free entry in the socket table */
i = 0; done = FALSE;
while ((i < UDP_MAX_HANDLES) && !done) {
kern_cli();
if ((udpTable[i].valid == FALSE)){
done = TRUE;
udpTable[i].valid = 2;
} else i++;
kern_sti();
}
/* No free entries: bind fail! */
if (!done) return -1;
/* Create a receive port for the socket */
udpTable[i].port = local->s_port;
sprintf(str,"UDP%d",i);
udpTable[i].hport = port_create(str,sizeof(UDP_MSG),4,STREAM,WRITE);
udpTable[i].pport = port_connect(str,sizeof(UDP_MSG),STREAM,READ);
udpTable[i].valid = TRUE;
/*
Request for the ethernet addresses associated to the IP addressed
given in the bindlist
*/
if (bindlist != NULL) {
while (*(int*)bindlist != 0) {
/* Ignore broadcast IP address */
if (!ip_compAddr(*bindlist,IPbroadcastaddress)) {
j = arp_req(*bindlist);
arp_sendRequest(j);
}
bindlist ++;
/* Search for a free entry in the socket table */
i = 0; done = FALSE;
while ((i < UDP_MAX_HANDLES) && !done) {
kern_cli();
if ((udpTable[i].valid == FALSE)) {
done = TRUE;
udpTable[i].valid = 2;
} else i++;
kern_sti();
}
}
 
return i;
/* No free entries: bind fail! */
if (!done)
return -1;
 
/* Create a receive port for the socket */
udpTable[i].port = local->s_port;
sprintf(str,"UDP%d",i);
udpTable[i].hport = port_create(str,sizeof(UDP_MSG),4,STREAM,WRITE);
udpTable[i].pport = port_connect(str,sizeof(UDP_MSG),STREAM,READ);
udpTable[i].valid = TRUE;
 
/*
* Request for the ethernet addresses associated to the IP addressed
* given in the bindlist.
*/
if (bindlist != NULL) {
while (*(int*)bindlist != 0) {
/* Ignore broadcast IP address */
if (!ip_compAddr(*bindlist,IPbroadcastaddress)) {
j = arp_req(*bindlist);
arp_sendRequest(j);
}
bindlist ++;
}
}
 
return i;
}
 
/* Send an UDP packet */
int udp_sendto(int s, void *buff, int nbytes, UDP_ADDR *to)
{
void *pkt;
UDP_HEADER *udphd;
char *msg;
void *pkt;
UDP_HEADER *udphd;
char *msg;
 
#ifdef __UDP_DBG__
static int num_pack = 0;
char str[50];
static int num_pack = 0;
#endif
WORD sum, old;
int i;
struct pseudo_hd ph;
WORD *p;
IP_ADDR *source;
 
pkt = netbuff_get(&udp_txbuff, BLOCK);
udphd = (UDP_HEADER *)ip_getFDB(pkt);
udphd->s_port = htons(udpTable[s].port);
udphd->d_port = htons(to->s_port);
udphd->mlen = htons((WORD)nbytes + sizeof(UDP_HEADER));
msg = (char *)(((BYTE *)udphd) + sizeof(UDP_HEADER));
if (nbytes > UDP_MAX_LEN) nbytes = UDP_MAX_LEN;
memcpy(msg,buff,nbytes);
WORD sum, old;
int i;
struct pseudo_hd ph;
WORD *p;
IP_ADDR *source;
 
source = ip_getAddr();
/* Compute the CheckSum */
udphd->checksum = 0;
for (i = 0; i < 4; i++) {
ph.source.ad[i] = source->ad[i];
ph.dest.ad[i] = to->s_addr.ad[i];
}
ph.zero = 0;
ph.protocoll = 17;
ph.len = udphd->mlen;
sum = 0; old = 0;
p = (WORD *)&ph;
for (i = 0; i < (sizeof(ph) >> 1); i++) {
sum += p[i];
if (sum < old) sum ++;
old = sum;
}
p = (WORD *)udphd;
((BYTE *)udphd)[ntohs(udphd->mlen)] = 0;
for (i = 0; i < ((ntohs(udphd->mlen) + 1) >> 1); i++) {
sum += p[i];
if (sum < old) sum++;
old = sum;
}
udphd->checksum = ~sum;
pkt = netbuff_get(&udp_txbuff, BLOCK);
udphd = (UDP_HEADER *)ip_getFDB(pkt);
udphd->s_port = htons(udpTable[s].port);
udphd->d_port = htons(to->s_port);
udphd->mlen = htons((WORD)nbytes + sizeof(UDP_HEADER));
msg = (char *)(((BYTE *)udphd) + sizeof(UDP_HEADER));
if (nbytes > UDP_MAX_LEN) nbytes = UDP_MAX_LEN;
memcpy(msg,buff,nbytes);
 
source = ip_getAddr();
/* Compute the CheckSum */
udphd->checksum = 0;
for (i = 0; i < 4; i++) {
ph.source.ad[i] = source->ad[i];
ph.dest.ad[i] = to->s_addr.ad[i];
}
ph.zero = 0;
ph.protocoll = 17;
ph.len = udphd->mlen;
sum = 0; old = 0;
p = (WORD *)&ph;
for (i = 0; i < (sizeof(ph) >> 1); i++) {
sum += p[i];
if (sum < old) sum ++;
old = sum;
}
p = (WORD *)udphd;
((BYTE *)udphd)[ntohs(udphd->mlen)] = 0;
for (i = 0; i < ((ntohs(udphd->mlen) + 1) >> 1); i++) {
sum += p[i];
if (sum < old) sum++;
old = sum;
}
udphd->checksum = ~sum;
ip_send(to->s_addr, pkt, ((WORD)nbytes + sizeof(UDP_HEADER)));
ip_send(to->s_addr, pkt, ((WORD)nbytes + sizeof(UDP_HEADER)));
#ifdef __UDP_DBG__
sprintf(str,"Packet sent %d; ",num_pack++);
win_puts(&dbg,str);
printk(KERN_DEBUG UDP_INFO "Packets sent: %d.\n", num_pack++);
#endif
return nbytes;
return nbytes;
}
 
void udp_init(void *dummy)
{
int i;
int i;
 
if (!udpIsInstalled) {
netbuff_init(&udp_rxbuff, UDP_RX_BUFFERS, UDP_MAX_LEN);
netbuff_init(&udp_txbuff, UDP_TX_BUFFERS, ETH_MAX_LEN);
if (!udpIsInstalled) {
netbuff_init(&udp_rxbuff, UDP_RX_BUFFERS, UDP_MAX_LEN);
netbuff_init(&udp_txbuff, UDP_TX_BUFFERS, ETH_MAX_LEN);
 
for (i = 0; i < UDP_MAX_HANDLES; i++) {
udpTable[i].valid = FALSE;
udpTable[i].notify = FALSE;
}
udpIsInstalled = TRUE;
} else cprintf("UDP: Already installed!!!\n");
for (i = 0; i < UDP_MAX_HANDLES; i++) {
udpTable[i].valid = FALSE;
udpTable[i].notify = FALSE;
}
udpIsInstalled = TRUE;
} else
printk(KERN_WARNING UDP_INFO ": Already installed.\n");
}