This source file includes following definitions.
- min
 
- raw_err
 
- raw_rcv
 
- raw_getfrag
 
- raw_getrawfrag
 
- raw_sendto
 
- raw_write
 
- raw_close
 
- raw_init
 
- raw_recvfrom
 
- raw_read
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28 
  29 
  30 
  31 
  32 
  33 
  34 
  35 
  36 #include <asm/system.h>
  37 #include <asm/segment.h>
  38 #include <linux/types.h>
  39 #include <linux/sched.h>
  40 #include <linux/errno.h>
  41 #include <linux/timer.h>
  42 #include <linux/mm.h>
  43 #include <linux/kernel.h>
  44 #include <linux/fcntl.h>
  45 #include <linux/socket.h>
  46 #include <linux/in.h>
  47 #include <linux/inet.h>
  48 #include <linux/netdevice.h>
  49 #include <net/ip.h>
  50 #include <net/protocol.h>
  51 #include <linux/skbuff.h>
  52 #include <net/sock.h>
  53 #include <net/icmp.h>
  54 #include <net/udp.h>
  55 #include <net/checksum.h>
  56 
  57 static inline unsigned long min(unsigned long a, unsigned long b)
     
  58 {
  59         if (a < b) 
  60                 return(a);
  61         return(b);
  62 }
  63 
  64 
  65 
  66 void raw_err (int err, unsigned char *header, unsigned long daddr,
     
  67          unsigned long saddr, struct inet_protocol *protocol)
  68 {
  69         struct sock *sk;
  70    
  71         if (protocol == NULL) 
  72                 return;
  73         sk = (struct sock *) protocol->data;
  74         if (sk == NULL) 
  75                 return;
  76 
  77         
  78         if ((err & 0xff00) == (ICMP_SOURCE_QUENCH << 8)) 
  79         {
  80                 if (sk->cong_window > 1) sk->cong_window = sk->cong_window/2;
  81                 return;
  82         }
  83 
  84         sk->err = icmp_err_convert[err & 0xff].errno;
  85         sk->error_report(sk);
  86   
  87         return;
  88 }
  89 
  90 
  91 
  92 
  93 
  94 
  95 
  96 
  97 int raw_rcv(struct sock *sk, struct sk_buff *skb, struct device *dev, long saddr, long daddr)
     
  98 {
  99         
 100         skb->sk = sk;
 101         skb_trim(skb,ntohs(skb->ip_hdr->tot_len));
 102         skb->h.raw = (unsigned char *) skb->ip_hdr;
 103         skb->dev = dev;
 104         skb->saddr = daddr;
 105         skb->daddr = saddr;
 106 
 107         
 108         
 109         if(sock_queue_rcv_skb(sk,skb)<0)
 110         {
 111                 ip_statistics.IpInDiscards++;
 112                 skb->sk=NULL;
 113                 kfree_skb(skb, FREE_READ);
 114                 return(0);
 115         }
 116 
 117         ip_statistics.IpInDelivers++;
 118         release_sock(sk);
 119         return(0);
 120 }
 121 
 122 
 123 
 124 
 125 
 126 
 127 
 128 
 129   
 130 static void raw_getfrag(const void *p, int saddr, char *to, unsigned int offset, unsigned int fraglen)
     
 131 {
 132         memcpy_fromfs(to, (const unsigned char *)p+offset, fraglen);
 133 }
 134 
 135 
 136 
 137 
 138  
 139 static void raw_getrawfrag(const void *p, int saddr, char *to, unsigned int offset, unsigned int fraglen)
     
 140 {
 141         memcpy_fromfs(to, (const unsigned char *)p+offset, fraglen);
 142         if(offset==0)
 143         {
 144                 struct iphdr *iph=(struct iphdr *)to;
 145                 iph->saddr=saddr;
 146                 iph->check=0;
 147                 iph->tot_len=htons(fraglen);    
 148 
 149                 
 150 
 151 
 152 
 153                 iph->id = htons(ip_id_count++);
 154                 iph->check=ip_fast_csum((unsigned char *)iph, iph->ihl);
 155         }
 156 }
 157 
 158 static int raw_sendto(struct sock *sk, const unsigned char *from, 
     
 159         int len, int noblock, unsigned flags, struct sockaddr_in *usin, int addr_len)
 160 {
 161         int err;
 162         struct sockaddr_in sin;
 163 
 164         
 165 
 166 
 167 
 168         if (flags & MSG_OOB)            
 169                 return -EOPNOTSUPP;
 170                          
 171         if (flags & ~MSG_DONTROUTE)
 172                 return(-EINVAL);
 173         
 174 
 175 
 176 
 177         if (usin) 
 178         {
 179                 if (addr_len < sizeof(sin)) 
 180                         return(-EINVAL);
 181                 memcpy(&sin, usin, sizeof(sin));
 182                 if (sin.sin_family && sin.sin_family != AF_INET) 
 183                         return(-EINVAL);
 184         }
 185         else 
 186         {
 187                 if (sk->state != TCP_ESTABLISHED) 
 188                         return(-EINVAL);
 189                 sin.sin_family = AF_INET;
 190                 sin.sin_port = sk->protocol;
 191                 sin.sin_addr.s_addr = sk->daddr;
 192         }
 193         if (sin.sin_port == 0) 
 194                 sin.sin_port = sk->protocol;
 195   
 196         if (sin.sin_addr.s_addr == INADDR_ANY)
 197                 sin.sin_addr.s_addr = ip_my_addr();
 198 
 199         if (sk->broadcast == 0 && ip_chk_addr(sin.sin_addr.s_addr)==IS_BROADCAST)
 200                 return -EACCES;
 201 
 202         if(sk->num==IPPROTO_RAW)
 203                 err=ip_build_xmit(sk, raw_getrawfrag, from, len, sin.sin_addr.s_addr, flags, sin.sin_port);
 204         else
 205                 err=ip_build_xmit(sk, raw_getfrag, from, len, sin.sin_addr.s_addr, flags, sin.sin_port);
 206         return err<0?err:len;
 207 }
 208 
 209 
 210 static int raw_write(struct sock *sk, const unsigned char *buff, int len, int noblock,
     
 211            unsigned flags)
 212 {
 213         return(raw_sendto(sk, buff, len, noblock, flags, NULL, 0));
 214 }
 215 
 216 
 217 static void raw_close(struct sock *sk, int timeout)
     
 218 {
 219         sk->state = TCP_CLOSE;
 220 }
 221 
 222 
 223 static int raw_init(struct sock *sk)
     
 224 {
 225         return(0);
 226 }
 227 
 228 
 229 
 230 
 231 
 232 
 233 
 234 int raw_recvfrom(struct sock *sk, unsigned char *to, int len,
     
 235      int noblock, unsigned flags, struct sockaddr_in *sin,
 236              int *addr_len)
 237 {
 238         int copied=0;
 239         struct sk_buff *skb;
 240         int err;
 241         int truesize;
 242 
 243         if (flags & MSG_OOB)
 244                 return -EOPNOTSUPP;
 245                 
 246         if (sk->shutdown & RCV_SHUTDOWN) 
 247                 return(0);
 248 
 249         if (addr_len) 
 250                 *addr_len=sizeof(*sin);
 251 
 252         skb=skb_recv_datagram(sk,flags,noblock,&err);
 253         if(skb==NULL)
 254                 return err;
 255 
 256         truesize=skb->len;
 257         copied = min(len, truesize);
 258   
 259         skb_copy_datagram(skb, 0, to, copied);
 260         sk->stamp=skb->stamp;
 261 
 262         
 263         if (sin) 
 264         {
 265                 sin->sin_family = AF_INET;
 266                 sin->sin_addr.s_addr = skb->daddr;
 267         }
 268         skb_free_datagram(skb);
 269         release_sock(sk);
 270         return (truesize);      
 271 }
 272 
 273 
 274 int raw_read (struct sock *sk, unsigned char *buff, int len, int noblock,unsigned flags)
     
 275 {
 276         return(raw_recvfrom(sk, buff, len, noblock, flags, NULL, NULL));
 277 }
 278 
 279 
 280 struct proto raw_prot = {
 281         sock_wmalloc,
 282         sock_rmalloc,
 283         sock_wfree,
 284         sock_rfree,
 285         sock_rspace,
 286         sock_wspace,
 287         raw_close,
 288         raw_read,
 289         raw_write,
 290         raw_sendto,
 291         raw_recvfrom,
 292         ip_build_header,
 293         udp_connect,
 294         NULL,
 295         ip_queue_xmit,
 296         NULL,
 297         NULL,
 298         NULL,
 299         NULL,
 300         datagram_select,
 301         NULL,
 302         raw_init,
 303         NULL,
 304         ip_setsockopt,
 305         ip_getsockopt,
 306         128,
 307         0,
 308         "RAW",
 309         0, 0,
 310         {NULL,}
 311 };