View | Details | Raw Unified | Return to bug 235909
Collapse All | Expand All

(-)/usr/ports/net/dual-dhclient/Makefile (-1 / +6 lines)
Lines 19-26 Link Here
19
NO_BUILD=	yes
19
NO_BUILD=	yes
20
20
21
PLIST_FILES=	sbin/dual-dhclient
21
PLIST_FILES=	sbin/dual-dhclient
22
22
PLIST_FILES+=	sbin/dual-dhclient-script
23
PLIST_FILES+=	sbin/dual-dhclient-script-locked
24
PLIST_FILES+=	"@sample etc/dual-dhclient.conf.sample"
23
do-install:
25
do-install:
24
	${INSTALL_SCRIPT} ${FILESDIR}/dual-dhclient ${STAGEDIR}${PREFIX}/sbin
26
	${INSTALL_SCRIPT} ${FILESDIR}/dual-dhclient ${STAGEDIR}${PREFIX}/sbin
27
	${INSTALL_SCRIPT} ${FILESDIR}/dual-dhclient-script ${STAGEDIR}${PREFIX}/sbin
28
	${INSTALL_SCRIPT} ${FILESDIR}/dual-dhclient-script-locked ${STAGEDIR}${PREFIX}/sbin
29
	${INSTALL_DATA} ${FILESDIR}/dual-dhclient.conf.sample ${STAGEDIR}${PREFIX}/etc
25
30
26
.include <bsd.port.mk>
31
.include <bsd.port.mk>
(-)/usr/ports/net/dual-dhclient/files/dual-dhclient (-2 / +24 lines)
Lines 4-8 Link Here
4
4
5
# Public domain
5
# Public domain
6
6
7
/sbin/dhclient "$@"
7
config="/usr/local/etc/dual-dhclient.conf"
8
/usr/local/sbin/dhclient -6 -nw -cf /dev/null "$@"
8
9
pid6=/var/run/dhclient6.pid
10
11
# stop dhclient6 if already running
12
pid=
13
[ -f "${pid6}" ] && pid=$(cat "${pid6}")
14
if [ -n "${pid}" ]
15
then
16
  cmd=$(ps -o comm= -p "${pid}")
17
  [ X"${cmd}" = X"dhclient" ] && kill "${pid}"
18
  while [ X"${cmd}" = X"dhclient" ]
19
  do
20
    sleep 1
21
    cmd=$(ps -o comm= -p "${pid}")
22
  done
23
fi
24
25
# use base dhclient for IPv4
26
/sbin/dhclient -c "${config}" "$@"
27
28
# use ISC dhclient for IPv6
29
# using DUID-LL (no timestamp) for easier static IPv6 allocation
30
/usr/local/sbin/dhclient -6 -nw -cf "${config}" -D LL "$@"
(-)/usr/ports/net/dual-dhclient/files/dual-dhclient-script (+4 lines)
Line 0 Link Here
1
#!/bin/sh
2
3
script="${0}-locked"
4
lockf /var/run/dhcp46.lock "${script}" "$@"
(-)/usr/ports/net/dual-dhclient/files/dual-dhclient-script-locked (+536 lines)
Line 0 Link Here
1
#!/bin/sh
2
#
3
# $Id: freebsd,v 1.24 2011/05/18 19:55:44 sar Exp $
4
#
5
# $FreeBSD$
6
7
if [ -x /usr/bin/logger ]; then
8
	LOGGER="/usr/bin/logger -s -p user.notice -t dhclient"
9
else
10
	LOGGER=echo
11
fi
12
13
make_resolv_conf() {
14
  old_domain_search=''
15
  old_domain_name_servers=''
16
  old_dhcp6_domain_search=''
17
  old_dhcp6_name_servers=''
18
  while read cmd param net
19
  do
20
    case "${cmd} ${net}" in
21
      ("search #IPv4")
22
        old_domain_search="${old_domain_search} ${param}"
23
        ;;
24
      ("search #IPv6")
25
        old_dhcp6_domain_search="${old_dhcp6_domain_search} ${param}"
26
        ;;
27
      ("nameserver #IPv4")
28
        old_domain_name_servers="${old_domain_name_servers} ${param}"
29
        ;;
30
      ("nameserver #IPv6")
31
        old_dhcp6_name_servers="${old_dhcp6_name_servers} ${param}"
32
        ;;
33
    esac
34
  done < /etc/resolv.conf
35
36
37
  if [ x"$new_domain_name_servers" != x ]; then
38
    ( cat /dev/null > /etc/resolv.conf.dhclient )
39
    exit_status=$?
40
    if [ $exit_status -ne 0 ]; then
41
      $LOGGER "Unable to create /etc/resolv.conf.dhclient: Error $exit_status"
42
    else
43
      if [ "x$new_domain_search" != x ]; then
44
	( echo "search ${new_domain_search} #IPv4" >> /etc/resolv.conf.dhclient )
45
	exit_status=$?
46
      elif [ "x$new_domain_name" != x ]; then
47
	# Note that the DHCP 'Domain Name Option' is really just a domain
48
	# name, and that this practice of using the domain name option as
49
	# a search path is both nonstandard and deprecated.
50
	( echo "search $new_domain_name #IPv4" >> /etc/resolv.conf.dhclient )
51
	exit_status=$?
52
      fi
53
54
      for search in ${old_dhcp6_domain_search}
55
      do
56
	if [ ${exit_status} -ne 0 ]; then
57
	  break
58
	fi
59
	( echo "search ${search} #IPv6" >> /etc/resolv.conf.dhclient )
60
	exit_status=$?
61
      done
62
63
      for nameserver in $new_domain_name_servers
64
      do
65
	if [ $exit_status -ne 0 ]; then
66
	  break
67
	fi
68
	( echo "nameserver ${nameserver} #IPv4" >>/etc/resolv.conf.dhclient )
69
	exit_status=$?
70
      done
71
      for nameserver in ${old_dhcp6_name_servers}
72
      do
73
	if [ $exit_status -ne 0 ]; then
74
	  break
75
	fi
76
	( echo "nameserver ${nameserver} #IPv6" >> /etc/resolv.conf.dhclient )
77
	exit_status=$?
78
      done
79
80
      # If there were no errors, attempt to mv the new file into place.
81
      if [ $exit_status -eq 0 ]; then
82
	( mv /etc/resolv.conf.dhclient /etc/resolv.conf )
83
	exit_status=$?
84
      fi
85
86
      if [ $exit_status -ne 0 ]; then
87
	$LOGGER "Error while writing new /etc/resolv.conf."
88
      fi
89
    fi
90
  elif [ "x${new_dhcp6_name_servers}" != x ] ; then
91
    ( cat /dev/null > /etc/resolv.conf.dhclient6 )
92
    exit_status=$?
93
    if [ $exit_status -ne 0 ] ; then
94
      $LOGGER "Unable to create /etc/resolv.conf.dhclient6: Error $exit_status"
95
    else
96
      if [ "x${new_dhcp6_domain_search}" != x ] ; then
97
	( echo "search ${new_dhcp6_domain_search} #IPv6" >> /etc/resolv.conf.dhclient6 )
98
	exit_status=$?
99
      fi
100
101
      for search in ${old_domain_search}
102
      do
103
	if [ ${exit_status} -ne 0 ]; then
104
	  break
105
	fi
106
	( echo "search ${search} #IPv4" >>/etc/resolv.conf.dhclient6 )
107
	exit_status=$?
108
      done
109
110
      for nameserver in ${new_dhcp6_name_servers} ; do
111
	if [ $exit_status -ne 0 ] ; then
112
	  break
113
	fi
114
	# If the nameserver has a link-local address
115
	# add a <zone_id> (interface name) to it.
116
	case $nameserver in
117
	    fe80:*) zone_id="%$interface";;
118
	    FE80:*) zone_id="%$interface";;
119
	    *)      zone_id="";;
120
	esac
121
	( echo "nameserver ${nameserver}$zone_id #IPv6" >> /etc/resolv.conf.dhclient6 )
122
	exit_status=$?
123
      done
124
125
      for nameserver in ${old_domain_name_servers}
126
      do
127
	if [ $exit_status -ne 0 ]; then
128
	  break
129
	fi
130
	( echo "nameserver ${nameserver} #IPv4" >>/etc/resolv.conf.dhclient6 )
131
	exit_status=$?
132
      done
133
134
135
      if [ $exit_status -eq 0 ] ; then
136
        ( mv /etc/resolv.conf.dhclient6 /etc/resolv.conf )
137
	exit_status=$?
138
      fi
139
140
      if [ $exit_status -ne 0 ] ; then
141
	$LOGGER "Error while writing new /etc/resolv.conf."
142
      fi
143
    fi
144
  fi
145
}
146
147
# Must be used on exit.   Invokes the local dhcp client exit hooks, if any.
148
exit_with_hooks() {
149
  exit_status=$1
150
  if [ -f /etc/dhclient-exit-hooks ]; then
151
    . /etc/dhclient-exit-hooks
152
  fi
153
# probably should do something with exit status of the local script
154
  exit $exit_status
155
}
156
157
# This function was largely borrowed from dhclient-script that
158
# ships with Centos, authored by Jiri Popelka and David Cantrell
159
# of Redhat. Thanks guys.
160
add_ipv6_addr_with_DAD() {
161
    ifconfig ${interface} inet6 ${new_ip6_address}/${new_ip6_prefixlen} alias
162
163
    if [ ${dad_wait_time} -le 0 ]
164
    then
165
        # if we're not waiting for DAD, assume we're good
166
        return 0
167
    fi
168
169
    # Repeatedly test whether newly added address passed
170
    # duplicate address detection (DAD)
171
    for i in $(seq 1 ${dad_wait_time}); do
172
        sleep 1 # give the DAD some time
173
174
        addr=$(ifconfig ${interface} \
175
            | grep "${new_ip6_address} prefixlen ${new_ip6_prefixlen}")
176
177
        # tentative flag == DAD is still not complete
178
        tentative=$(echo "${addr}" | grep tentative)
179
        # dadfailed flag == address is already in use somewhere else
180
        dadfailed=$(echo "${addr}" | grep duplicated)
181
182
        if [ -n "${dadfailed}" ] ; then
183
            # dad failed, remove the address
184
            ifconfig ${interface} inet6 ${new_ip6_address}/${new_ip6_prefixlen} -alias
185
            exit_with_hooks 3
186
        fi
187
188
        if [ -z "${tentative}" ] ; then
189
            if [ -n "${addr}" ]; then
190
                # DAD is over
191
                return 0
192
            else
193
                # address was auto-removed (or not added at all)
194
                exit_with_hooks 3
195
            fi
196
        fi
197
    done
198
199
    return 0
200
}
201
202
# Invoke the local dhcp client enter hooks, if they exist.
203
if [ -f /etc/dhclient-enter-hooks ]; then
204
  exit_status=0
205
  . /etc/dhclient-enter-hooks
206
  # allow the local script to abort processing of this state
207
  # local script must set exit_status variable to nonzero.
208
  if [ $exit_status -ne 0 ]; then
209
    exit $exit_status
210
  fi
211
fi
212
213
if [ x$new_network_number != x ]; then
214
   $LOGGER New Network Number: $new_network_number
215
fi
216
217
if [ x$new_broadcast_address != x ]; then
218
 $LOGGER New Broadcast Address: $new_broadcast_address
219
  new_broadcast_arg="broadcast $new_broadcast_address"
220
fi
221
if [ x$old_broadcast_address != x ]; then
222
  old_broadcast_arg="broadcast $old_broadcast_address"
223
fi
224
if [ x$new_subnet_mask != x ]; then
225
  new_netmask_arg="netmask $new_subnet_mask"
226
fi
227
if [ x$old_subnet_mask != x ]; then
228
  old_netmask_arg="netmask $old_subnet_mask"
229
fi
230
if [ x$alias_subnet_mask != x ]; then
231
  alias_subnet_arg="netmask $alias_subnet_mask"
232
fi
233
if [ x$new_interface_mtu != x ]; then
234
  mtu_arg="mtu $new_interface_mtu"
235
fi
236
if [ x$IF_METRIC != x ]; then
237
  metric_arg="metric $IF_METRIC"
238
fi
239
240
if [ x$reason = xMEDIUM ]; then
241
  eval "ifconfig $interface $medium"
242
  eval "ifconfig $interface inet -alias 0.0.0.0 $medium" >/dev/null 2>&1
243
  sleep 1
244
  exit_with_hooks 0
245
fi
246
247
###
248
### DHCPv4 Handlers
249
###
250
251
if [ x$reason = xPREINIT ]; then
252
  if [ x$alias_ip_address != x ]; then
253
    ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
254
    route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
255
  fi
256
  ifconfig $interface inet 0.0.0.0 netmask 0.0.0.0 \
257
		broadcast 255.255.255.255 up
258
  exit_with_hooks 0
259
fi
260
261
if [ x$reason = xARPCHECK ] || [ x$reason = xARPSEND ]; then
262
  exit_with_hooks 0;
263
fi
264
  
265
if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
266
   [ x$reason = xREBIND ] || [ x$reason = xREBOOT ]; then
267
  current_hostname=`/bin/hostname`
268
  if [ x$current_hostname = x ] || \
269
     [ x$current_hostname = x$old_host_name ]; then
270
    if [ x$current_hostname = x ] || \
271
       [ x$new_host_name != x$old_host_name ]; then
272
      $LOGGER "New Hostname: $new_host_name"
273
      hostname $new_host_name
274
    fi
275
  fi
276
  if [ x$old_ip_address != x ] && [ x$alias_ip_address != x ] && \
277
		[ x$alias_ip_address != x$old_ip_address ]; then
278
    ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
279
    route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
280
  fi
281
  if [ x$old_ip_address != x ] && [ x$old_ip_address != x$new_ip_address ]
282
   then
283
    eval "ifconfig $interface inet -alias $old_ip_address $medium"
284
    route delete $old_ip_address 127.1 >/dev/null 2>&1
285
    for router in $old_routers; do
286
      route delete default $router >/dev/null 2>&1
287
    done
288
    if [ -n "$old_static_routes" ]; then
289
      set -- $old_static_routes
290
      while [ $# -gt 1 ]; do
291
	route delete $1 $2
292
	shift; shift
293
      done
294
    fi
295
    arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -d \1/p' |sh
296
  fi
297
  if [ x$old_ip_address = x ] || [ x$old_ip_address != x$new_ip_address ] || \
298
     [ x$reason = xBOUND ] || [ x$reason = xREBOOT ]; then
299
    eval "ifconfig $interface inet $new_ip_address $new_netmask_arg \
300
			$new_broadcast_arg $mtu_arg $metric_arg $medium"
301
    $LOGGER "New IP Address ($interface): $new_ip_address"
302
    $LOGGER "New Subnet Mask ($interface): $new_subnet_mask"
303
    $LOGGER "New Broadcast Address ($interface): $new_broadcast_address"
304
    if [ -n "$new_routers" ]; then
305
      $LOGGER "New Routers: $new_routers"
306
    fi
307
    route add $new_ip_address 127.1 >/dev/null 2>&1
308
    for router in $new_routers; do
309
      # If the subnet is captive, eg the netmask is /32 but the default
310
      # gateway is (obviously) outside of this, then we need to produce a
311
      # host route to reach the gateway.
312
      if [ "x$new_subnet_mask" = "x255.255.255.255" ] ; then
313
	route add -host $router -interface $interface
314
      fi
315
      route add default $router >/dev/null 2>&1
316
    done
317
    if [ -n "$new_static_routes" ]; then
318
      $LOGGER "New Static Routes: $new_static_routes"
319
      set -- $new_static_routes
320
      while [ $# -gt 1 ]; do
321
	route add $1 $2
322
	shift; shift
323
      done
324
    fi
325
  else                                                                        
326
    # we haven't changed the address, have we changed other options           
327
    # that we wish to update?
328
    if [ x$new_routers != x ] && [ x$new_routers != x$old_routers ] ; then
329
      # if we've changed routers delete the old and add the new.
330
      $LOGGER "New Routers: $new_routers"
331
      for router in $old_routers; do
332
        route delete default $router >/dev/null 2>&1
333
      done
334
      for router in $new_routers; do
335
        # If the subnet is captive, eg the netmask is /32 but the default
336
        # gateway is (obviously) outside of this, then we need to produce a
337
        # host route to reach the gateway.
338
        if [ "x$new_subnet_mask" = "x255.255.255.255" ] ; then
339
          route add -host $router -interface $interface
340
        fi
341
        route add default $router >/dev/null 2>&1
342
      done
343
    fi
344
  fi
345
  if [ x$new_ip_address != x$alias_ip_address ] && [ x$alias_ip_address != x ];
346
   then
347
    ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
348
    route add $alias_ip_address 127.0.0.1
349
  fi
350
  make_resolv_conf
351
  exit_with_hooks 0
352
fi
353
354
if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ] || [ x$reason = xRELEASE ] \
355
   || [ x$reason = xSTOP ]; then
356
  if [ x$alias_ip_address != x ]; then
357
    ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
358
    route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
359
  fi
360
  if [ x$old_ip_address != x ]; then
361
    eval "ifconfig $interface inet -alias $old_ip_address $medium"
362
    route delete $old_ip_address 127.1 >/dev/null 2>&1
363
    for router in $old_routers; do
364
      route delete default $router >/dev/null 2>&1
365
    done
366
    if [ -n "$old_static_routes" ]; then
367
      set -- $old_static_routes
368
      while [ $# -gt 1 ]; do
369
	route delete $1 $2
370
	shift; shift
371
      done
372
    fi
373
    arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -d \1/p' \
374
						|sh >/dev/null 2>&1
375
  fi
376
  if [ x$alias_ip_address != x ]; then
377
    ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
378
    route add $alias_ip_address 127.0.0.1
379
  fi
380
  exit_with_hooks 0
381
fi
382
383
if [ x$reason = xTIMEOUT ]; then
384
  if [ x$alias_ip_address != x ]; then
385
    ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
386
    route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
387
  fi
388
  eval "ifconfig $interface inet $new_ip_address $new_netmask_arg \
389
			$new_broadcast_arg $mtu_arg $metric_arg $medium"
390
  $LOGGER "New IP Address ($interface): $new_ip_address"
391
  $LOGGER "New Subnet Mask ($interface): $new_subnet_mask"
392
  $LOGGER "New Broadcast Address ($interface): $new_broadcast_address"
393
  sleep 1
394
  if [ -n "$new_routers" ]; then
395
    $LOGGER "New Routers: $new_routers"
396
    set -- $new_routers
397
    if ping -q -c 1 $1; then
398
      if [ x$new_ip_address != x$alias_ip_address ] && \
399
			[ x$alias_ip_address != x ]; then
400
	ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
401
	route add $alias_ip_address 127.0.0.1
402
      fi
403
      route add $new_ip_address 127.1 >/dev/null 2>&1
404
      for router in $new_routers; do
405
	if [ "x$new_subnet_mask" = "x255.255.255.255" ] ; then
406
	  route add -host $router -interface $interface
407
	fi
408
	route add default $router >/dev/null 2>&1
409
      done
410
      set -- $new_static_routes
411
      while [ $# -gt 1 ]; do
412
	route add $1 $2
413
	shift; shift
414
      done
415
      make_resolv_conf
416
      exit_with_hooks 0
417
    fi
418
  fi
419
  eval "ifconfig $interface inet -alias $new_ip_address $medium"
420
  for router in $old_routers; do
421
    route delete default $router >/dev/null 2>&1
422
  done
423
  if [ -n "$old_static_routes" ]; then
424
    set -- $old_static_routes
425
    while [ $# -gt 1 ]; do
426
      route delete $1 $2
427
      shift; shift
428
    done
429
  fi
430
  arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -d \1/p' \
431
							|sh >/dev/null 2>&1
432
  exit_with_hooks 1
433
fi
434
435
###
436
### DHCPv6 Handlers
437
###
438
439
if [ ${reason} = PREINIT6 ] ; then
440
  # Ensure interface is up.
441
  ifconfig ${interface} up
442
443
  # XXX: Remove any stale addresses from aborted clients.
444
445
  # We need to give the kernel some time to active interface
446
  interface_up_wait_time=5
447
  for i in $(seq 0 ${interface_up_wait_time})
448
  do
449
      ifconfig ${interface} | grep inactive >/dev/null 2>&1
450
      if [ $? -ne 0 ]; then
451
          break;
452
      fi
453
      sleep 1
454
  done
455
456
  # Wait for duplicate address detection for this interface if the
457
  # --dad-wait-time parameter has been specified and is greater than
458
  # zero.
459
  if [ ${dad_wait_time} -gt 0 ]; then
460
      # Check if any IPv6 address on this interface is marked as
461
      # tentative.
462
      ifconfig ${interface} | grep inet6 | grep tentative \
463
          >/dev/null 2>&1
464
      if [ $? -eq 0 ]; then
465
          # Wait for duplicate address detection to complete or for
466
          # the timeout specified as --dad-wait-time.
467
          for i in $(seq 0 $dad_wait_time)
468
          do
469
              # We're going to poll for the tentative flag every second.
470
              sleep 1
471
              ifconfig ${interface} | grep inet6 | grep tentative \
472
                  >/dev/null 2>&1
473
              if [ $? -ne 0 ]; then
474
                  break;
475
              fi
476
          done
477
      fi
478
  fi
479
480
481
  exit_with_hooks 0
482
fi
483
484
if [ x${old_ip6_prefix} != x ] || [ x${new_ip6_prefix} != x ] ; then
485
    echo Prefix ${reason} old=${old_ip6_prefix} new=${new_ip6_prefix}
486
487
    exit_with_hooks 0
488
fi
489
490
if [ ${reason} = BOUND6 ] ; then
491
  if [ x${new_ip6_address} = x ] || [ x${new_ip6_prefixlen} = x ] ; then
492
    exit_with_hooks 2;
493
  fi
494
495
  # Add address to interface, check for DAD if dad_wait_time > 0
496
  add_ipv6_addr_with_DAD
497
498
  # Check for nameserver options.
499
  make_resolv_conf
500
501
  exit_with_hooks 0
502
fi
503
504
if [ ${reason} = RENEW6 ] || [ ${reason} = REBIND6 ] ; then
505
  # Make sure nothing has moved around on us.
506
507
  # Nameservers/domains/etc.
508
  if [ "x${new_dhcp6_name_servers}" != "x${old_dhcp6_name_servers}" ] ||
509
     [ "x${new_dhcp6_domain_search}" != "x${old_dhcp6_domain_search}" ] ; then
510
    make_resolv_conf
511
  fi
512
513
  exit_with_hooks 0
514
fi
515
516
if [ ${reason} = DEPREF6 ] ; then
517
  if [ x${new_ip6_address} = x ] ; then
518
    exit_with_hooks 2;
519
  fi
520
521
  ifconfig ${interface} inet6 ${new_ip6_address} deprecated
522
523
  exit_with_hooks 0
524
fi
525
526
if [ ${reason} = EXPIRE6 -o ${reason} = RELEASE6 -o ${reason} = STOP6 ] ; then
527
  if [ x${old_ip6_address} = x ] || [ x${old_ip6_prefixlen} = x ] ; then
528
    exit_with_hooks 2;
529
  fi
530
531
  ifconfig ${interface} inet6 ${old_ip6_address}/${old_ip6_prefixlen} -alias
532
533
  exit_with_hooks 0
534
fi
535
536
exit_with_hooks 0
(-)/usr/ports/net/dual-dhclient/files/dual-dhclient.conf.sample (+4 lines)
Line 0 Link Here
1
# dual-dhclient.conf
2
3
#lease-id-format hex;
4
script "/usr/local/sbin/dual-dhclient-script";

Return to bug 235909