1 /* udp_usrreq.c 4.5 81/11/16 */ 2 3 #include "../h/param.h" 4 #include "../h/dir.h" 5 #include "../h/user.h" 6 #include "../h/mbuf.h" 7 #include "../h/protosw.h" 8 #include "../h/socket.h" 9 #include "../h/socketvar.h" 10 #include "../h/inaddr.h" 11 #include "../net/inet.h" 12 #include "../net/inet_host.h" 13 #include "../net/inet_pcb.h" 14 #include "../net/inet_systm.h" 15 #include "../net/ip.h" 16 #include "../net/ip_var.h" 17 #include "../net/udp.h" 18 #include "../net/udp_var.h" 19 20 udp_init() 21 { 22 23 udb.inp_next = udb.inp_prev = &udb; 24 } 25 26 int udpcksum; 27 28 udp_input(m) 29 struct mbuf *m; 30 { 31 register struct udpiphdr *ui; 32 register struct inpcb *inp; 33 u_short lport, fport, ulen; 34 35 ui = mtod(m, struct udpiphdr *); 36 if (ui->ui_len > sizeof (struct ip)) /* XXX */ 37 ip_stripoptions((struct ip *)ui); 38 ulen = ((struct ip *)ui)->ip_len; 39 ui->ui_len = htons(ulen); 40 ui->ui_prev = ui->ui_next = 0; 41 ui->ui_x1 = 0; 42 lport = ntohs(ui->ui_dport); 43 fport = ntohs(ui->ui_sport); 44 if (sizeof (struct udpiphdr) > m->m_len) 45 { printf("udp header overflow\n"); m_freem(m); return; } 46 if (udpcksum) { 47 (void) inet_cksum(m, sizeof (struct ip) + ulen); 48 if (ui->ui_sum) { 49 printf("udp cksum %x\n", ui->ui_sum); 50 m_freem(m); 51 return; 52 } 53 } 54 inp = in_pcblookup(&udb, &ui->ui_src, fport, &ui->ui_dst, lport); 55 if (inp == 0) 56 goto notwanted; 57 /* stuff on queue using some subroutine */ 58 return; 59 notwanted: 60 m_freem(m); 61 /* gen icmp? */ 62 } 63 64 udp_ctlinput(m) 65 struct mbuf *m; 66 { 67 68 m_freem(m); 69 } 70 71 udp_ctlinput(m) 72 struct mbuf *m; 73 { 74 75 m_freem(m); 76 } 77 78 /*ARGSUSED*/ 79 udp_output(raddr, rport, m) 80 int raddr, rport; 81 struct mbuf *m; 82 { 83 84 /* setup header */ 85 ip_output(m); 86 } 87 88 /*ARGSUSED*/ 89 udp_usrreq(so, req, m, addr) 90 struct socket *so; 91 int req; 92 struct mbuf *m; 93 caddr_t addr; 94 { 95 struct inpcb *inp = sotoinpcb(so); 96 int error; 97 98 switch (req) { 99 100 case PRU_ATTACH: 101 if (inp != 0) 102 return (EINVAL); 103 inp = in_pcballoc(); 104 if (inp == NULL) 105 return (ENOBUFS); 106 so->so_pcb = (caddr_t)inp; 107 break; 108 109 case PRU_DETACH: 110 if (inp == 0) 111 return (ENOTCONN); 112 in_pcbfree(inp); 113 break; 114 115 case PRU_CONNECT: 116 if (inp->inp_fhost) 117 return (EISCONN); 118 inp->inp_fhost = in_hosteval((struct inaddr *)addr, &error); 119 if (inp->inp_fhost == 0) 120 return (error); 121 soisconnected(so); 122 break; 123 124 case PRU_DISCONNECT: 125 if (inp->inp_fhost == 0) 126 return (ENOTCONN); 127 in_hostfree(inp->inp_fhost); 128 inp->inp_fhost = 0; 129 soisdisconnected(so); 130 break; 131 132 case PRU_FLUSH: 133 return (EOPNOTSUPP); 134 135 case PRU_SHUTDOWN: 136 socantsendmore(so); 137 break; 138 139 case PRU_SEND: 140 #if 0 141 if (addr) { 142 if (inp->inp_fhost) 143 return (EISCONN); 144 udp_output(addr->in_fhost, addr->in_fport, m); 145 } else 146 #endif 147 udp_output(inp->inp_fhost->h_addr, ip->inp_fport, m); 148 break; 149 150 case PRU_ABORT: 151 in_pcbfree(inp); 152 sofree(so); 153 soisdisconnected(so); 154 break; 155 156 case PRU_CONTROL: 157 return (EOPNOTSUPP); 158 159 default: 160 panic("udp_usrreq"); 161 } 162 return (0); 163 } 164 165 udp_sense() 166 { 167 168 } 169