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"); |
} |